mirror of
https://github.com/Syping/dtranslatebot.git
synced 2024-11-22 13:50:22 +01:00
basic impl of database system
This commit is contained in:
parent
fb94e44c7d
commit
a26763df96
7 changed files with 539 additions and 43 deletions
|
@ -30,12 +30,32 @@ database::~database()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool database::add_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const bot::settings::target &target)
|
void database::add_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const bot::settings::target &target)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::cerr << "[Debug] database::add_channel_target(dpp::snowflake, dpp::snowflake, const bot::settings::target&) have being called." << std::endl;
|
std::cerr << "[Debug] database::add_channel_target(dpp::snowflake, dpp::snowflake, const bot::settings::target&) have being called." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
void database::delete_channel(dpp::snowflake guild_id, dpp::snowflake channel_id)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
std::cerr << "[Debug] database::delete_channel(dpp::snowflake, dpp::snowflake) have being called." << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void database::delete_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
std::cerr << "[Debug] database::delete_channel_target(dpp::snowflake, dpp::snowflake, const std::string&) have being called." << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void database::delete_guild(dpp::snowflake guild_id)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
std::cerr << "[Debug] database::delete_guild(dpp::snowflake) have being called." << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::variant<std::monostate,bot::settings::target> database::find_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target)
|
std::variant<std::monostate,bot::settings::target> database::find_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target)
|
||||||
|
@ -78,10 +98,17 @@ std::vector<dpp::snowflake> database::get_guilds()
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool database::set_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &source)
|
void database::set_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &source)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::cerr << "[Debug] database::set_channel_source(dpp::snowflake, dpp::snowflake, const std::string&) have being called." << std::endl;
|
std::cerr << "[Debug] database::set_channel_source(dpp::snowflake, dpp::snowflake, const std::string&) have being called." << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool database::sync()
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
std::cerr << "[Debug] database::sync() have being called." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,17 +23,26 @@
|
||||||
|
|
||||||
namespace bot {
|
namespace bot {
|
||||||
namespace database {
|
namespace database {
|
||||||
|
struct guild {
|
||||||
|
dpp::snowflake id;
|
||||||
|
std::vector<dpp::snowflake> channel;
|
||||||
|
};
|
||||||
|
|
||||||
class database {
|
class database {
|
||||||
public:
|
public:
|
||||||
explicit database();
|
explicit database();
|
||||||
virtual ~database();
|
virtual ~database();
|
||||||
virtual bool add_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const bot::settings::target &target);
|
virtual void add_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const bot::settings::target &target);
|
||||||
|
virtual void delete_channel(dpp::snowflake guild_id, dpp::snowflake channel_id);
|
||||||
|
virtual void delete_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target);
|
||||||
|
virtual void delete_guild(dpp::snowflake guild_id);
|
||||||
virtual std::variant<std::monostate,bot::settings::target> find_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target);
|
virtual std::variant<std::monostate,bot::settings::target> find_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target);
|
||||||
virtual std::vector<dpp::snowflake> get_channels(dpp::snowflake guild_id);
|
virtual std::vector<dpp::snowflake> get_channels(dpp::snowflake guild_id);
|
||||||
virtual std::string get_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id);
|
virtual std::string get_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id);
|
||||||
virtual std::vector<bot::settings::target> get_channel_targets(dpp::snowflake guild_id, dpp::snowflake channel_id);
|
virtual std::vector<bot::settings::target> get_channel_targets(dpp::snowflake guild_id, dpp::snowflake channel_id);
|
||||||
virtual std::vector<dpp::snowflake> get_guilds();
|
virtual std::vector<dpp::snowflake> get_guilds();
|
||||||
virtual bool set_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &source);
|
virtual void set_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &source);
|
||||||
|
virtual bool sync();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,21 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <cctype>
|
||||||
|
#include <dpp/discordclient.h>
|
||||||
|
#include <dpp/json.h>
|
||||||
|
#include <dpp/utility.h>
|
||||||
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
#include "database_file.h"
|
#include "database_file.h"
|
||||||
using namespace bot::database;
|
using namespace bot::database;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
file::file(const std::filesystem::path &storage_path) : m_storagePath(storage_path)
|
file::file(const std::filesystem::path &storage_path) : m_storagePath(storage_path)
|
||||||
{
|
{
|
||||||
std::cout << "[Launch] Checking storage directory..." << std::endl;
|
std::cout << "[Launch] Checking storage directory..." << std::endl;
|
||||||
if (!std::filesystem::exists(storage_path)) {
|
if (!std::filesystem::is_directory(storage_path)) {
|
||||||
std::cerr << "[Error] Storage directory " << storage_path << " can not be found" << std::endl;
|
std::cerr << "[Error] Storage directory " << storage_path << " can not be found" << std::endl;
|
||||||
throw std::runtime_error("Storage directory can not be found");
|
throw std::runtime_error("Storage directory can not be found");
|
||||||
}
|
}
|
||||||
|
@ -57,63 +64,493 @@ file::file(const std::filesystem::path &storage_path) : m_storagePath(storage_pa
|
||||||
|
|
||||||
file::~file()
|
file::~file()
|
||||||
{
|
{
|
||||||
|
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
close(fd);
|
close(fd);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool file::add_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const bot::settings::target &target)
|
void file::add_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const bot::settings::target &target)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
std::cerr << "[Debug] database::add_channel_target(dpp::snowflake, dpp::snowflake, const bot::settings::target&) have being called." << std::endl;
|
for (auto guild = m_dataCache.begin(); guild != m_dataCache.end(); guild++) {
|
||||||
#endif
|
if (guild->id == guild_id) {
|
||||||
return false;
|
for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) {
|
||||||
|
if (channel->id == channel_id) {
|
||||||
|
for (auto _target = channel->targets.begin(); _target != channel->targets.end(); _target++) {
|
||||||
|
if (_target->target == target.target) {
|
||||||
|
_target->webhook = target.webhook;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
channel->targets.push_back(target);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot::settings::channel channel;
|
||||||
|
cache_channel(channel_id, &channel);
|
||||||
|
channel.targets.push_back(target);
|
||||||
|
guild->channel.push_back(std::move(channel));
|
||||||
|
cache_add_channel(guild_id, channel_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot::settings::channel channel;
|
||||||
|
cache_channel(channel_id, &channel);
|
||||||
|
channel.targets.push_back(target);
|
||||||
|
|
||||||
|
bot::settings::guild guild;
|
||||||
|
guild.id = guild_id;
|
||||||
|
guild.channel.push_back(std::move(channel));
|
||||||
|
cache_add_channel(guild_id, channel_id);
|
||||||
|
|
||||||
|
m_dataCache.push_back(std::move(guild));
|
||||||
|
}
|
||||||
|
|
||||||
|
void file::delete_channel(dpp::snowflake guild_id, dpp::snowflake channel_id)
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
|
|
||||||
|
for (auto guild = m_dataCache.begin(); guild != m_dataCache.end(); guild++) {
|
||||||
|
if (guild->id == guild_id) {
|
||||||
|
for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) {
|
||||||
|
if (channel->id == channel_id) {
|
||||||
|
guild->channel.erase(channel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto guild = m_channelCache.begin(); guild != m_channelCache.end(); guild++) {
|
||||||
|
if (guild->id == guild_id) {
|
||||||
|
for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) {
|
||||||
|
if (*channel == channel_id) {
|
||||||
|
guild->channel.erase(channel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<dpp::snowflake> channels;
|
||||||
|
cache_guild(guild_id, &channels);
|
||||||
|
for (auto channel = channels.begin(); channel != channels.end(); channel++) {
|
||||||
|
if (*channel == channel_id) {
|
||||||
|
channels.erase(channel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot::database::guild _guild;
|
||||||
|
_guild.id = guild_id;
|
||||||
|
_guild.channel = std::move(channels);
|
||||||
|
m_channelCache.push_back(std::move(_guild));
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::filesystem::path channel_file = m_storagePath / "channel" / (std::to_string(channel_id) + ".json");
|
||||||
|
std::filesystem::remove(channel_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void file::delete_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target)
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
|
|
||||||
|
for (auto guild = m_dataCache.begin(); guild != m_dataCache.end(); guild++) {
|
||||||
|
if (guild->id == guild_id) {
|
||||||
|
for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) {
|
||||||
|
if (channel->id == channel_id) {
|
||||||
|
for (auto _target = channel->targets.begin(); _target != channel->targets.end(); _target++) {
|
||||||
|
if (_target->target == target) {
|
||||||
|
channel->targets.erase(_target);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot::settings::channel channel;
|
||||||
|
cache_channel(channel_id, &channel);
|
||||||
|
for (auto _target = channel.targets.begin(); _target != channel.targets.end(); _target++) {
|
||||||
|
if (_target->target == target) {
|
||||||
|
channel.targets.erase(_target);
|
||||||
|
guild->channel.push_back(std::move(channel));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot::settings::channel channel;
|
||||||
|
cache_channel(channel_id, &channel);
|
||||||
|
for (auto _target = channel.targets.begin(); _target != channel.targets.end(); _target++) {
|
||||||
|
if (_target->target == target) {
|
||||||
|
channel.targets.erase(_target);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot::settings::guild guild;
|
||||||
|
guild.id = guild_id;
|
||||||
|
guild.channel.push_back(std::move(channel));
|
||||||
|
|
||||||
|
m_dataCache.push_back(std::move(guild));
|
||||||
|
}
|
||||||
|
|
||||||
|
void file::delete_guild(dpp::snowflake guild_id)
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
|
|
||||||
|
for (auto guild = m_dataCache.begin(); guild != m_dataCache.end(); guild++) {
|
||||||
|
if (guild->id == guild_id) {
|
||||||
|
m_dataCache.erase(guild);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto guild = m_channelCache.begin(); guild != m_channelCache.end(); guild++) {
|
||||||
|
if (guild->id == guild_id) {
|
||||||
|
m_channelCache.erase(guild);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::filesystem::path guild_file = m_storagePath / "guild" / (std::to_string(guild_id) + ".json");
|
||||||
|
std::filesystem::remove(guild_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::variant<std::monostate,bot::settings::target> file::find_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target)
|
std::variant<std::monostate,bot::settings::target> file::find_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
std::cerr << "[Debug] database::find_channel_target(dpp::snowflake, dpp::snowflake, const std::string&) have being called." << std::endl;
|
|
||||||
#endif
|
for (auto guild = m_dataCache.begin(); guild != m_dataCache.end(); guild++) {
|
||||||
|
if (guild->id == guild_id) {
|
||||||
|
for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) {
|
||||||
|
if (channel->id == channel_id) {
|
||||||
|
for (auto _target = channel->targets.begin(); _target != channel->targets.end(); _target++) {
|
||||||
|
if (_target->target == target)
|
||||||
|
return *_target;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot::settings::channel channel;
|
||||||
|
cache_channel(channel_id, &channel);
|
||||||
|
for (auto _target = channel.targets.begin(); _target != channel.targets.end(); _target++) {
|
||||||
|
if (_target->target == target) {
|
||||||
|
return *_target;
|
||||||
|
}
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<dpp::snowflake> file::get_channels(dpp::snowflake guild_id)
|
std::vector<dpp::snowflake> file::get_channels(dpp::snowflake guild_id)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
std::cerr << "[Debug] database::get_channels(dpp::snowflake) have being called." << std::endl;
|
|
||||||
#endif
|
for (auto guild = m_channelCache.begin(); guild != m_channelCache.end(); guild++) {
|
||||||
return {};
|
if (guild->id == guild_id) {
|
||||||
|
return guild->channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<dpp::snowflake> channels;
|
||||||
|
cache_guild(guild_id, &channels);
|
||||||
|
return channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string file::get_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id)
|
std::string file::get_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
std::cerr << "[Debug] database::get_channel_source(dpp::snowflake, dpp::snowflake) have being called." << std::endl;
|
|
||||||
#endif
|
for (auto guild = m_dataCache.begin(); guild != m_dataCache.end(); guild++) {
|
||||||
return {};
|
if (guild->id == guild_id) {
|
||||||
|
for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) {
|
||||||
|
if (channel->id == channel_id)
|
||||||
|
return channel->source;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot::settings::channel channel;
|
||||||
|
cache_channel(channel_id, &channel);
|
||||||
|
return channel.source;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<bot::settings::target> file::get_channel_targets(dpp::snowflake guild_id, dpp::snowflake channel_id)
|
std::vector<bot::settings::target> file::get_channel_targets(dpp::snowflake guild_id, dpp::snowflake channel_id)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
std::cerr << "[Debug] database::get_channel_targets(dpp::snowflake, dpp::snowflake) have being called." << std::endl;
|
|
||||||
#endif
|
for (auto guild = m_dataCache.begin(); guild != m_dataCache.end(); guild++) {
|
||||||
return {};
|
if (guild->id == guild_id) {
|
||||||
|
for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) {
|
||||||
|
if (channel->id == channel_id) {
|
||||||
|
return channel->targets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot::settings::channel channel;
|
||||||
|
cache_channel(channel_id, &channel);
|
||||||
|
return channel.targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<dpp::snowflake> file::get_guilds()
|
std::vector<dpp::snowflake> file::get_guilds()
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
std::cerr << "[Debug] database::get_guilds() have being called." << std::endl;
|
std::vector<dpp::snowflake> guilds;
|
||||||
#endif
|
list_guilds(&guilds);
|
||||||
return {};
|
return guilds;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool file::set_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &source)
|
void file::set_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &source)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
std::cerr << "[Debug] database::set_channel_source(dpp::snowflake, dpp::snowflake, const std::string&) have being called." << std::endl;
|
|
||||||
#endif
|
for (auto guild = m_dataCache.begin(); guild != m_dataCache.end(); guild++) {
|
||||||
return false;
|
if (guild->id == guild_id) {
|
||||||
|
for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) {
|
||||||
|
if (channel->id == channel_id) {
|
||||||
|
channel->source = source;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot::settings::channel channel;
|
||||||
|
cache_channel(channel_id, &channel);
|
||||||
|
channel.source = source;
|
||||||
|
guild->channel.push_back(std::move(channel));
|
||||||
|
cache_add_channel(guild_id, channel_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot::settings::channel channel;
|
||||||
|
cache_channel(channel_id, &channel);
|
||||||
|
channel.source = source;
|
||||||
|
|
||||||
|
bot::settings::guild guild;
|
||||||
|
guild.id = guild_id;
|
||||||
|
guild.channel.push_back(std::move(channel));
|
||||||
|
cache_add_channel(guild_id, channel_id);
|
||||||
|
|
||||||
|
m_dataCache.push_back(std::move(guild));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool file::sync()
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||||
|
|
||||||
|
const std::filesystem::path channel_dir = m_storagePath / "channel";
|
||||||
|
bool channel_dir_exists = std::filesystem::is_directory(channel_dir);
|
||||||
|
if (!channel_dir_exists)
|
||||||
|
channel_dir_exists = std::filesystem::create_directory(channel_dir);
|
||||||
|
|
||||||
|
if (channel_dir_exists) {
|
||||||
|
for (auto guild = m_dataCache.begin(); guild != m_dataCache.end(); guild++) {
|
||||||
|
for (auto channel = guild->channel.begin(); channel != guild->channel.end();) {
|
||||||
|
dpp::json target_json;
|
||||||
|
for (auto target = channel->targets.begin(); target != channel->targets.end(); target++) {
|
||||||
|
target_json[target->target] = {
|
||||||
|
std::to_string(target->webhook.id), target->webhook.token
|
||||||
|
};
|
||||||
|
}
|
||||||
|
dpp::json channel_json = {
|
||||||
|
{"source"s, channel->source},
|
||||||
|
{"target"s, target_json}
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::filesystem::path channel_file = m_storagePath / "channel" / (std::to_string(channel->id) + ".json");
|
||||||
|
std::ofstream ofs(channel_file, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||||
|
if (ofs.is_open()) {
|
||||||
|
ofs << channel_json.dump();
|
||||||
|
bool ok = ofs.good();
|
||||||
|
ofs.close();
|
||||||
|
if (ok)
|
||||||
|
channel = guild->channel.erase(channel);
|
||||||
|
else
|
||||||
|
channel++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
channel++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "[Error] Storage channel directory can not be created" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::filesystem::path guild_dir = m_storagePath / "guild";
|
||||||
|
bool guild_dir_exists = std::filesystem::is_directory(guild_dir);
|
||||||
|
if (!guild_dir_exists)
|
||||||
|
guild_dir_exists = std::filesystem::create_directory(guild_dir);
|
||||||
|
|
||||||
|
if (guild_dir_exists) {
|
||||||
|
for (auto guild = m_channelCache.begin(); guild != m_channelCache.end();) {
|
||||||
|
dpp::json guild_json;
|
||||||
|
for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++)
|
||||||
|
guild_json.push_back(std::to_string(*channel));
|
||||||
|
|
||||||
|
const std::filesystem::path guild_file = m_storagePath / "guild" / (std::to_string(guild->id) + ".json");
|
||||||
|
std::ofstream ofs(guild_file, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||||
|
if (ofs.is_open()) {
|
||||||
|
ofs << guild_json.dump();
|
||||||
|
bool ok = ofs.good();
|
||||||
|
ofs.close();
|
||||||
|
if (ok)
|
||||||
|
guild = m_channelCache.erase(guild);
|
||||||
|
else
|
||||||
|
guild++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
guild++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "[Error] Storage guild directory can not be created" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void file::cache_add_channel(dpp::snowflake guild_id, dpp::snowflake channel_id)
|
||||||
|
{
|
||||||
|
for (auto guild = m_channelCache.begin(); guild != m_channelCache.end(); guild++) {
|
||||||
|
if (guild->id == guild_id) {
|
||||||
|
if (std::find(guild->channel.begin(), guild->channel.end(), channel_id) == guild->channel.end())
|
||||||
|
guild->channel.push_back(channel_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<dpp::snowflake> channels;
|
||||||
|
cache_guild(guild_id, &channels);
|
||||||
|
if (std::find(channels.begin(), channels.end(), channel_id) == channels.end())
|
||||||
|
channels.push_back(channel_id);
|
||||||
|
|
||||||
|
bot::database::guild guild;
|
||||||
|
guild.id = guild_id;
|
||||||
|
guild.channel = std::move(channels);
|
||||||
|
m_channelCache.push_back(std::move(guild));
|
||||||
|
}
|
||||||
|
|
||||||
|
void file::cache_channel(dpp::snowflake channel_id, bot::settings::channel *channel)
|
||||||
|
{
|
||||||
|
channel->id = channel_id;
|
||||||
|
|
||||||
|
const std::filesystem::path channel_file = m_storagePath / "channel" / (std::to_string(channel_id) + ".json");
|
||||||
|
|
||||||
|
if (!std::filesystem::is_regular_file(channel_file))
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::ifstream ifs(channel_file, std::ios::in | std::ios::binary);
|
||||||
|
if (!ifs.is_open())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string sdata(std::istreambuf_iterator<char>{ifs}, {});
|
||||||
|
ifs.close();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const dpp::json json = dpp::json::parse(sdata);
|
||||||
|
if (json.is_object()) {
|
||||||
|
auto json_channel_source = json.find("source");
|
||||||
|
if (json_channel_source != json.end())
|
||||||
|
channel->source = *json_channel_source;
|
||||||
|
|
||||||
|
auto json_channel_target = json.find("target");
|
||||||
|
if (json_channel_target != json.end()) {
|
||||||
|
if (json_channel_target->is_object()) {
|
||||||
|
for (auto json_target = json_channel_target->begin(); json_target != json_channel_target->end(); json_target++) {
|
||||||
|
bot::settings::target target;
|
||||||
|
target.target = json_target.key();
|
||||||
|
if (json_target->is_array()) {
|
||||||
|
if (json_target->size() == 2) {
|
||||||
|
target.webhook.id = std::stoull(std::string(json_target->front()));
|
||||||
|
target.webhook.token = json_target->back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (json_target->is_string()) {
|
||||||
|
target.webhook = dpp::webhook(*json_target);
|
||||||
|
}
|
||||||
|
channel->targets.push_back(std::move(target));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::exception &exception) {
|
||||||
|
std::cerr << "[Exception] " << exception.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void file::cache_guild(dpp::snowflake guild_id, std::vector<dpp::snowflake> *channels)
|
||||||
|
{
|
||||||
|
const std::filesystem::path guild_file = m_storagePath / "guild" / (std::to_string(guild_id) + ".json");
|
||||||
|
|
||||||
|
if (!std::filesystem::is_regular_file(guild_file))
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::ifstream ifs(guild_file, std::ios::in | std::ios::binary);
|
||||||
|
if (!ifs.is_open())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string sdata(std::istreambuf_iterator<char>{ifs}, {});
|
||||||
|
ifs.close();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const dpp::json json = dpp::json::parse(sdata);
|
||||||
|
if (json.is_array()) {
|
||||||
|
for (auto channel = json.begin(); channel != json.end(); channel++) {
|
||||||
|
if (channel->is_number())
|
||||||
|
channels->push_back(*channel);
|
||||||
|
else if (channel->is_string())
|
||||||
|
channels->push_back(std::stoull(std::string(*channel)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::exception &exception) {
|
||||||
|
std::cerr << "[Exception] " << exception.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void file::list_guilds(std::vector<dpp::snowflake> *guilds)
|
||||||
|
{
|
||||||
|
const std::filesystem::path guild_dir = m_storagePath / "guild";
|
||||||
|
|
||||||
|
if (!std::filesystem::is_directory(guild_dir))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const auto &guild_file : std::filesystem::directory_iterator(guild_dir)) {
|
||||||
|
const std::filesystem::path &guild_file_path = guild_file.path();
|
||||||
|
if (guild_file_path.extension() == "json") {
|
||||||
|
const std::string &guild_filename = guild_file_path.filename();
|
||||||
|
if (std::all_of(guild_filename.begin(), guild_filename.end(), ::isdigit)) {
|
||||||
|
try {
|
||||||
|
dpp::snowflake guild_id = std::stoull(guild_filename);
|
||||||
|
guilds->push_back(guild_id);
|
||||||
|
}
|
||||||
|
catch (const std::exception &exception) {
|
||||||
|
std::cerr << "[Exception] " << exception.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void file::sync_exec_async()
|
||||||
|
{
|
||||||
|
std::thread thread(&file::sync, this);
|
||||||
|
thread.detach();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,18 +29,30 @@ namespace bot {
|
||||||
public:
|
public:
|
||||||
explicit file(const std::filesystem::path &storage_path);
|
explicit file(const std::filesystem::path &storage_path);
|
||||||
~file();
|
~file();
|
||||||
bool add_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const bot::settings::target &target) override;
|
void add_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const bot::settings::target &target) override;
|
||||||
|
void delete_channel(dpp::snowflake guild_id, dpp::snowflake channel_id) override;
|
||||||
|
void delete_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target) override;
|
||||||
|
void delete_guild(dpp::snowflake guild_id) override;
|
||||||
std::variant<std::monostate,bot::settings::target> find_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target) override;
|
std::variant<std::monostate,bot::settings::target> find_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target) override;
|
||||||
std::vector<dpp::snowflake> get_channels(dpp::snowflake guild_id) override;
|
std::vector<dpp::snowflake> get_channels(dpp::snowflake guild_id) override;
|
||||||
std::string get_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id) override;
|
std::string get_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id) override;
|
||||||
std::vector<bot::settings::target> get_channel_targets(dpp::snowflake guild_id, dpp::snowflake channel_id) override;
|
std::vector<bot::settings::target> get_channel_targets(dpp::snowflake guild_id, dpp::snowflake channel_id) override;
|
||||||
std::vector<dpp::snowflake> get_guilds() override;
|
std::vector<dpp::snowflake> get_guilds() override;
|
||||||
bool set_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &source) override;
|
void set_channel_source(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &source) override;
|
||||||
|
bool sync() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void cache_add_channel(dpp::snowflake guild_id, dpp::snowflake channel_id);
|
||||||
|
void cache_delete_channel(dpp::snowflake guild_id, dpp::snowflake channel_id);
|
||||||
|
void cache_channel(dpp::snowflake channel_id, bot::settings::channel *channel);
|
||||||
|
void cache_guild(dpp::snowflake guild_id, std::vector<dpp::snowflake> *channels);
|
||||||
|
void list_guilds(std::vector<dpp::snowflake> *guilds);
|
||||||
|
void sync_exec_async();
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
int fd;
|
int fd;
|
||||||
#endif
|
#endif
|
||||||
|
std::vector<bot::database::guild> m_channelCache;
|
||||||
|
std::vector<bot::settings::guild> m_dataCache;
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
std::filesystem::path m_storagePath;
|
std::filesystem::path m_storagePath;
|
||||||
};
|
};
|
||||||
|
|
|
@ -79,13 +79,18 @@ void bot::slashcommands::process_translate_command(dpp::cluster *bot, bot::setti
|
||||||
bot::settings::target s_target;
|
bot::settings::target s_target;
|
||||||
s_target.target = target;
|
s_target.target = target;
|
||||||
s_target.webhook = webhook;
|
s_target.webhook = webhook;
|
||||||
s_channel.targets.push_back(std::move(s_target));
|
s_channel.targets.push_back(s_target);
|
||||||
|
|
||||||
settings->lock();
|
settings->lock();
|
||||||
settings->add_channel(s_channel, event.command.guild_id);
|
settings->add_channel(s_channel, event.command.guild_id);
|
||||||
settings->add_translatebot_webhook(webhook.id);
|
settings->add_translatebot_webhook(webhook.id);
|
||||||
|
auto database = settings->get_database();
|
||||||
settings->unlock();
|
settings->unlock();
|
||||||
|
|
||||||
|
database->set_channel_source(event.command.guild_id, event.command.channel_id, source);
|
||||||
|
database->add_channel_target(event.command.guild_id, event.command.channel_id, s_target);
|
||||||
|
database->sync(); // do async later
|
||||||
|
|
||||||
event.reply(dpp::message("Channel will be now translated!").set_flags(dpp::m_ephemeral));
|
event.reply(dpp::message("Channel will be now translated!").set_flags(dpp::m_ephemeral));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -97,13 +102,18 @@ void bot::slashcommands::process_translate_command(dpp::cluster *bot, bot::setti
|
||||||
bot::settings::target s_target;
|
bot::settings::target s_target;
|
||||||
s_target.target = target;
|
s_target.target = target;
|
||||||
s_target.webhook = *webhook;
|
s_target.webhook = *webhook;
|
||||||
s_channel.targets.push_back(std::move(s_target));
|
s_channel.targets.push_back(s_target);
|
||||||
|
|
||||||
settings->lock();
|
settings->lock();
|
||||||
settings->add_channel(s_channel, event.command.guild_id);
|
settings->add_channel(s_channel, event.command.guild_id);
|
||||||
settings->add_translatebot_webhook(webhook->id);
|
settings->add_translatebot_webhook(webhook->id);
|
||||||
|
auto database = settings->get_database();
|
||||||
settings->unlock();
|
settings->unlock();
|
||||||
|
|
||||||
|
database->set_channel_source(event.command.guild_id, event.command.channel_id, source);
|
||||||
|
database->add_channel_target(event.command.guild_id, event.command.channel_id, s_target);
|
||||||
|
database->sync(); // do async later
|
||||||
|
|
||||||
event.reply(dpp::message("Channel will be now translated!").set_flags(dpp::m_ephemeral));
|
event.reply(dpp::message("Channel will be now translated!").set_flags(dpp::m_ephemeral));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,11 +46,11 @@ const std::vector<language> libretranslate::get_languages()
|
||||||
|
|
||||||
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.value();
|
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.value();
|
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));
|
languages.push_back(std::move(language));
|
||||||
|
@ -89,7 +89,7 @@ const std::string libretranslate::translate(const std::string &text, const std::
|
||||||
if (response.is_object()) {
|
if (response.is_object()) {
|
||||||
auto tr_text = response.find("translatedText");
|
auto tr_text = response.find("translatedText");
|
||||||
if (tr_text != response.end())
|
if (tr_text != response.end())
|
||||||
return tr_text.value();
|
return *tr_text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,8 @@ void bot::webhook_push::push_request(dpp::snowflake webhook_id, const std::strin
|
||||||
{
|
{
|
||||||
std::promise<dpp::http_request_completion_t> _p;
|
std::promise<dpp::http_request_completion_t> _p;
|
||||||
std::future<dpp::http_request_completion_t> _f = _p.get_future();
|
std::future<dpp::http_request_completion_t> _f = _p.get_future();
|
||||||
bot->post_rest(API_PATH "/webhooks", std::to_string(webhook_id), dpp::utility::url_encode(webhook_token), dpp::m_post, json, [bot, &_p](dpp::json &json, const dpp::http_request_completion_t &event) {
|
bot->post_rest(API_PATH "/webhooks", std::to_string(webhook_id), dpp::utility::url_encode(webhook_token), dpp::m_post, json, [&bot, &_p](dpp::json &json, const dpp::http_request_completion_t &event) {
|
||||||
|
std::cout << event.body << std::endl;
|
||||||
if (event.status != 204)
|
if (event.status != 204)
|
||||||
std::cerr << "[Warning] Webhook push returned unexpected code " << event.status << std::endl;
|
std::cerr << "[Warning] Webhook push returned unexpected code " << event.status << std::endl;
|
||||||
_p.set_value(event);
|
_p.set_value(event);
|
||||||
|
|
Loading…
Reference in a new issue