delete channel from settings when no target is left

- converted some pointers to references
- simplified some constructors
This commit is contained in:
Syping 2024-03-07 23:30:33 +01:00
parent c8239e2517
commit 616ce0055b
7 changed files with 142 additions and 131 deletions

View file

@ -22,14 +22,6 @@
#include "database.h"
using namespace bot::database;
database::database()
{
}
database::~database()
{
}
void database::add_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const bot::settings::target &target)
{
#ifndef NDEBUG

View file

@ -30,8 +30,8 @@ namespace bot {
class database {
public:
explicit database();
virtual ~database();
explicit database() = default;
virtual ~database() = default;
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);

View file

@ -24,14 +24,14 @@
#include "../translator/libretranslate/libretranslate.h"
using namespace bot::settings;
void process_database_channels(std::shared_ptr<bot::database::database> database, bot::settings::guild *guild, std::vector<dpp::snowflake> *webhookIds)
void process_database_channels(std::shared_ptr<bot::database::database> database, bot::settings::guild &guild, std::vector<dpp::snowflake> &webhookIds)
{
const std::vector<dpp::snowflake> db_channels = database->get_channels(guild->id);
const std::vector<dpp::snowflake> db_channels = database->get_channels(guild.id);
for (auto db_channel_id = db_channels.begin(); db_channel_id != db_channels.end(); db_channel_id++) {
bool channel_found = false;
for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) {
for (auto channel = guild.channel.begin(); channel != guild.channel.end(); channel++) {
if (channel->id == *db_channel_id) {
const bot::settings::channel db_channel = database->get_channel(guild->id, channel->id);
const bot::settings::channel db_channel = database->get_channel(guild.id, channel->id);
if (!db_channel.source.empty())
channel->source = db_channel.source;
for (auto db_target = db_channel.targets.begin(); db_target != db_channel.targets.end(); db_target++) {
@ -39,14 +39,14 @@ void process_database_channels(std::shared_ptr<bot::database::database> database
for (auto target = channel->targets.begin(); target != channel->targets.end(); target++) {
if (target->target == db_target->target) {
target->webhook = db_target->webhook;
webhookIds->push_back(db_target->webhook.id);
webhookIds.push_back(db_target->webhook.id);
target_found = true;
break;
}
}
if (!target_found) {
channel->targets.push_back(*db_target);
webhookIds->push_back(db_target->webhook.id);
webhookIds.push_back(db_target->webhook.id);
}
}
channel_found = true;
@ -54,23 +54,23 @@ void process_database_channels(std::shared_ptr<bot::database::database> database
}
}
if (!channel_found) {
const bot::settings::channel db_channel = database->get_channel(guild->id, *db_channel_id);
guild->channel.push_back(db_channel);
const bot::settings::channel db_channel = database->get_channel(guild.id, *db_channel_id);
guild.channel.push_back(db_channel);
for (auto db_target = db_channel.targets.begin(); db_target != db_channel.targets.end(); db_target++)
webhookIds->push_back(db_target->webhook.id);
webhookIds.push_back(db_target->webhook.id);
}
}
}
void process_database(std::shared_ptr<bot::database::database> database, std::vector<guild> *guilds, std::vector<dpp::snowflake> *webhookIds)
void process_database(std::shared_ptr<bot::database::database> database, std::vector<guild> &guilds, std::vector<dpp::snowflake> &webhookIds)
{
std::cout << "[Launch] Loading database..." << std::endl;
const std::vector<dpp::snowflake> db_guilds = database->get_guilds();
for (auto db_guild_id = db_guilds.begin(); db_guild_id != db_guilds.end(); db_guild_id++) {
bool guild_found = false;
for (auto guild = guilds->begin(); guild != guilds->end(); guild++) {
for (auto guild = guilds.begin(); guild != guilds.end(); guild++) {
if (guild->id == *db_guild_id) {
process_database_channels(database, &*guild, webhookIds);
process_database_channels(database, *guild, webhookIds);
guild_found = true;
break;
}
@ -78,13 +78,13 @@ void process_database(std::shared_ptr<bot::database::database> database, std::ve
if (!guild_found) {
bot::settings::guild guild;
guild.id = *db_guild_id;
process_database_channels(database, &guild, webhookIds);
guilds->push_back(std::move(guild));
process_database_channels(database, guild, webhookIds);
guilds.push_back(std::move(guild));
}
}
}
void process_guild_settings(const dpp::json &json, std::vector<guild> *guilds, std::vector<dpp::snowflake> *webhookIds)
void process_guild_settings(const dpp::json &json, std::vector<guild> &guilds, std::vector<dpp::snowflake> &webhookIds)
{
for (auto json_guild = json.begin(); json_guild != json.end(); json_guild++) {
if (json_guild->is_object()) {
@ -128,7 +128,7 @@ void process_guild_settings(const dpp::json &json, std::vector<guild> *guilds, s
target target;
target.target = *json_channel_target;
target.webhook = dpp::webhook(json_channel->at("webhook"));
webhookIds->push_back(target.webhook.id);
webhookIds.push_back(target.webhook.id);
channel.targets.push_back(std::move(target));
}
else if (json_channel_target->is_object()) {
@ -136,7 +136,7 @@ void process_guild_settings(const dpp::json &json, std::vector<guild> *guilds, s
target target;
target.target = json_target.key();
target.webhook = dpp::webhook(*json_target);
webhookIds->push_back(target.webhook.id);
webhookIds.push_back(target.webhook.id);
channel.targets.push_back(std::move(target));
}
}
@ -146,7 +146,7 @@ void process_guild_settings(const dpp::json &json, std::vector<guild> *guilds, s
guild.channel.push_back(std::move(channel));
}
}
guilds->push_back(std::move(guild));
guilds.push_back(std::move(guild));
}
}
}
@ -162,63 +162,63 @@ void process_preflang_settings(const dpp::json &json, std::vector<std::string> *
}
}
void process_user_settings(const dpp::json &json, uint16_t *avatar_size)
void process_user_settings(const dpp::json &json, uint16_t &avatar_size)
{
auto json_avatar_size = json.find("avatar_size");
if (json_avatar_size != json.end()) {
*avatar_size = *json_avatar_size;
if (*avatar_size < 16)
*avatar_size = 16;
else if (*avatar_size > 4096)
*avatar_size = 4096;
avatar_size = *json_avatar_size;
if (avatar_size < 16)
avatar_size = 16;
else if (avatar_size > 4096)
avatar_size = 4096;
}
}
void process_url(const std::string &url, translator *translator)
void process_url(const std::string &url, translator &translator)
{
std::string_view url_v = url;
if (url_v.substr(0, 7) == "http://") {
translator->tls = false;
if (!translator->port)
translator->port = 80;
translator.tls = false;
if (!translator.port)
translator.port = 80;
url_v = url_v.substr(7);
}
else if (url_v.substr(0, 8) == "https://") {
translator->tls = true;
if (!translator->port)
translator->port = 443;
translator.tls = true;
if (!translator.port)
translator.port = 443;
url_v = url_v.substr(8);
}
else {
translator->tls = false;
if (!translator->port)
translator->port = 80;
translator.tls = false;
if (!translator.port)
translator.port = 80;
}
auto slash_pos = url_v.find_first_of('/');
if (slash_pos != std::string_view::npos) {
translator->url = url_v.substr(slash_pos);
translator.url = url_v.substr(slash_pos);
url_v = url_v.substr(0, slash_pos);
}
else {
translator->url = "/";
translator.url = "/";
url_v = url_v.substr(0, slash_pos);
}
// We don't have IPv6 support here yet
auto colon_pos = url_v.find_last_of(':');
if (colon_pos != std::string_view::npos) {
translator->hostname = url_v.substr(0, colon_pos);
translator.hostname = url_v.substr(0, colon_pos);
const int port = std::stoi(std::string(url_v.substr(colon_pos + 1)));
if (port > 0 && port < 65536)
translator->port = static_cast<uint16_t>(port);
translator.port = static_cast<uint16_t>(port);
else
throw std::invalid_argument("Port is out of range");
}
else {
translator->hostname = url_v;
translator.hostname = url_v;
}
}
bool process_translator_settings(const dpp::json &json, translator *translator)
bool process_translator_settings(const dpp::json &json, translator &translator)
{
if (!json.is_object()) {
std::cerr << "[Error] Value translator needs to be a object" << std::endl;
@ -227,39 +227,39 @@ bool process_translator_settings(const dpp::json &json, translator *translator)
auto json_translate_hostname = json.find("hostname");
if (json_translate_hostname != json.end())
translator->hostname = *json_translate_hostname;
translator.hostname = *json_translate_hostname;
else
translator->hostname = {};
translator.hostname = {};
auto json_translate_tls = json.find("tls");
if (json_translate_tls != json.end())
translator->tls = *json_translate_tls;
translator.tls = *json_translate_tls;
else
translator->tls = false;
translator.tls = false;
auto json_translate_port = json.find("port");
if (json_translate_port != json.end())
translator->port = *json_translate_port;
translator.port = *json_translate_port;
else
translator->port = 0;
translator.port = 0;
auto json_translate_url = json.find("url");
if (json_translate_url == json.end()) {
std::cerr << "[Error] Value url not found in translator object" << std::endl;
return false;
}
if (translator->hostname.empty()) {
if (translator.hostname.empty()) {
process_url(*json_translate_url, translator);
}
else {
translator->url = *json_translate_url;
translator.url = *json_translate_url;
}
auto json_translate_apiKey = json.find("apiKey");
if (json_translate_apiKey != json.end())
translator->apiKey = *json_translate_apiKey;
translator.apiKey = *json_translate_apiKey;
else
translator->apiKey.clear();
translator.apiKey.clear();
return true;
}
@ -301,6 +301,16 @@ void settings::add_translatebot_webhook(dpp::snowflake webhook_id)
m_webhookIds.push_back(webhook_id);
}
void settings::erase_channel(guild *guild, dpp::snowflake channel_id)
{
for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) {
if (channel->id == channel_id) {
guild->channel.erase(channel);
return;
}
}
}
void settings::erase_translatebot_webhook(dpp::snowflake webhook_id)
{
const std::lock_guard<std::recursive_mutex> guard(m_mutex);
@ -315,9 +325,9 @@ uint16_t settings::avatar_size()
return m_avatarSize;
}
channel* settings::get_channel(guild *guild, dpp::snowflake channel_id)
channel* settings::get_channel(guild &guild, dpp::snowflake channel_id)
{
for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) {
for (auto channel = guild.channel.begin(); channel != guild.channel.end(); channel++) {
if (channel->id == channel_id)
return &*channel;
}
@ -484,12 +494,12 @@ bool settings::parse(const std::string &data, bool initialize)
std::cerr << "[Error] Value translator not found" << std::endl;
return false;
}
if (!process_translator_settings(*json_translator, &m_translator))
if (!process_translator_settings(*json_translator, m_translator))
return false;
auto json_guilds = json.find("guilds");
if (json_guilds != json.end() && json_guilds->is_object())
process_guild_settings(*json_guilds, &m_guilds, &m_webhookIds);
process_guild_settings(*json_guilds, m_guilds, m_webhookIds);
auto json_preflangs = json.find("preferred_lang");
if (json_preflangs != json.end() && json_preflangs->is_array())
@ -497,9 +507,9 @@ bool settings::parse(const std::string &data, bool initialize)
auto json_user = json.find("user");
if (json_user != json.end() && json_user->is_object())
process_user_settings(*json_user, &m_avatarSize);
process_user_settings(*json_user, m_avatarSize);
process_database(m_database, &m_guilds, &m_webhookIds);
process_database(m_database, m_guilds, m_webhookIds);
return true;
}

View file

@ -33,11 +33,12 @@ namespace bot {
void add_translatebot_webhook(dpp::snowflake webhook_id);
/* erase functions */
static void erase_channel(guild *guild, dpp::snowflake channel_id);
void erase_translatebot_webhook(dpp::snowflake webhook_id);
/* get functions */
uint16_t avatar_size();
static channel* get_channel(guild *guild, dpp::snowflake channel_id);
static channel* get_channel(guild &guild, dpp::snowflake channel_id);
channel* get_channel(dpp::snowflake guild_id, dpp::snowflake channel_id);
guild* get_guild(dpp::snowflake guild_id);
target* get_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target);
@ -59,6 +60,11 @@ namespace bot {
bool parse(const std::string &data, bool initialize = true);
bool parse_file(const std::string &filename, bool initialize = true);
/* prevent copies */
settings() = default;
settings(const settings&) = delete;
settings& operator=(const settings&) = delete;
private:
mutable std::recursive_mutex m_mutex;
size_t m_externallyLockedCount = 0;

View file

@ -40,65 +40,76 @@ void bot::slashcommands::process_edit_command(dpp::cluster *bot, bot::settings::
dpp::command_interaction interaction = event.command.get_command_interaction();
if (interaction.options[0].name == "delete") {
const std::lock_guard<bot::settings::settings> guard(*settings);
if (bot::settings::channel *channel = settings->get_channel(event.command.guild_id, event.command.channel_id)) {
const std::string target = std::get<std::string>(event.get_parameter("target"));
if (bot::settings::guild *guild = settings->get_guild(event.command.guild_id)) {
if (bot::settings::channel *channel = settings->get_channel(*guild, event.command.channel_id)) {
const std::string target = std::get<std::string>(event.get_parameter("target"));
std::shared_ptr<bot::database::database> database = settings->get_database();
const bot::settings::channel db_channel = database->get_channel(event.command.guild_id, event.command.channel_id);
auto database = settings->get_database();
const bot::settings::channel db_channel = database->get_channel(event.command.guild_id, event.command.channel_id);
if (db_channel.targets.empty()) {
event.reply(dpp::message("The current channel has no deleteable targets!").set_flags(dpp::m_ephemeral));
}
else if (target == "**") {
std::vector<std::string> targets;
for (auto db_target = db_channel.targets.begin(); db_target != db_channel.targets.end(); db_target++) {
targets.push_back(db_target->target);
if (db_channel.targets.empty()) {
event.reply(dpp::message("The current channel has no deleteable targets!").set_flags(dpp::m_ephemeral));
}
for (auto target = channel->targets.begin(); target != channel->targets.end();) {
if (std::find(targets.begin(), targets.end(), target->target) != targets.end()) {
bot->delete_webhook(target->webhook.id, std::bind(&bot::slashcommands::process_deleted_webhook, settings, target->webhook.id, std::placeholders::_1));
target = channel->targets.erase(target);
else if (target == "**") {
std::vector<std::string> targets;
for (auto db_target = db_channel.targets.begin(); db_target != db_channel.targets.end(); db_target++) {
targets.push_back(db_target->target);
}
else {
target++;
for (auto target = channel->targets.begin(); target != channel->targets.end();) {
if (std::find(targets.begin(), targets.end(), target->target) != targets.end()) {
bot->delete_webhook(target->webhook.id, std::bind(&bot::slashcommands::process_deleted_webhook, settings, target->webhook.id, std::placeholders::_1));
target = channel->targets.erase(target);
}
else {
target++;
}
}
database->delete_channel(event.command.guild_id, event.command.channel_id);
database->sync();
if (channel->targets.empty())
settings->erase_channel(guild, event.command.channel_id);
event.reply(dpp::message("Deleteable targets have being deleted!").set_flags(dpp::m_ephemeral));
}
database->delete_channel(event.command.guild_id, event.command.channel_id);
database->sync();
event.reply(dpp::message("Deleteable targets have being deleted!").set_flags(dpp::m_ephemeral));
}
else {
bool target_found = false;
for (auto db_target = db_channel.targets.begin(); db_target != db_channel.targets.end(); db_target++) {
if (db_target->target == target) {
target_found = true;
break;
}
}
if (target_found) {
for (auto _target = channel->targets.begin(); _target != channel->targets.end(); _target++) {
if (_target->target == target) {
bot->delete_webhook(_target->webhook.id, std::bind(&bot::slashcommands::process_deleted_webhook, settings, _target->webhook.id, std::placeholders::_1));
channel->targets.erase(_target);
else {
bool target_found = false;
for (auto db_target = db_channel.targets.begin(); db_target != db_channel.targets.end(); db_target++) {
if (db_target->target == target) {
target_found = true;
break;
}
}
if (db_channel.targets.size() == 1)
database->delete_channel(event.command.guild_id, event.command.channel_id);
else
database->delete_channel_target(event.command.guild_id, event.command.channel_id, target);
database->sync();
if (target_found) {
for (auto _target = channel->targets.begin(); _target != channel->targets.end(); _target++) {
if (_target->target == target) {
bot->delete_webhook(_target->webhook.id, std::bind(&bot::slashcommands::process_deleted_webhook, settings, _target->webhook.id, std::placeholders::_1));
channel->targets.erase(_target);
break;
}
}
event.reply(dpp::message("Target have being deleted!").set_flags(dpp::m_ephemeral));
}
else {
event.reply(dpp::message("Target language is not being found or deleteable!").set_flags(dpp::m_ephemeral));
if (db_channel.targets.size() == 1)
database->delete_channel(event.command.guild_id, event.command.channel_id);
else
database->delete_channel_target(event.command.guild_id, event.command.channel_id, target);
database->sync();
if (channel->targets.empty())
settings->erase_channel(guild, event.command.channel_id);
event.reply(dpp::message("Target have being deleted!").set_flags(dpp::m_ephemeral));
}
else {
event.reply(dpp::message("Target language is not being found or deleteable!").set_flags(dpp::m_ephemeral));
}
}
}
else {
event.reply(dpp::message("The current channel is not being translated!").set_flags(dpp::m_ephemeral));
}
}
else {
event.reply(dpp::message("The current channel is not being translated!").set_flags(dpp::m_ephemeral));
@ -123,7 +134,7 @@ void bot::slashcommands::process_edit_command(dpp::cluster *bot, bot::settings::
if (source_valid) {
channel->source = source;
std::shared_ptr<bot::database::database> database = settings->get_database();
auto database = settings->get_database();
database->set_channel_source(event.command.guild_id, event.command.channel_id, source);
database->sync();
@ -171,7 +182,7 @@ void bot::slashcommands::process_list_command(dpp::cluster *bot, bot::settings::
// We want give more information to users who can Manage Webhooks
dpp::permission user_permissions = event.command.get_resolved_permission(event.command.usr.id);
if (user_permissions.has(dpp::p_manage_webhooks)) {
std::shared_ptr<bot::database::database> database = settings->get_database();
auto database = settings->get_database();
const bot::settings::channel db_channel = database->get_channel(event.command.guild_id, event.command.channel_id);
for (auto target = channel->targets.begin(); target != channel->targets.end(); target++) {
@ -268,13 +279,13 @@ void bot::slashcommands::process_translate_command(dpp::cluster *bot, bot::setti
dpp::command_interaction interaction = event.command.get_command_interaction();
if (interaction.options[0].name == "channel") {
v_target = event.command.get_resolved_channel(
std::get<dpp::snowflake>(event.get_parameter("channel")));
std::get<dpp::snowflake>(event.get_parameter("channel")));
}
else if (interaction.options[0].name == "webhook") {
v_target = dpp::webhook(std::get<std::string>(event.get_parameter("webhook")));
}
const std::vector<bot::translator::language> languages = settings->get_translator()->get_languages();
const auto languages = settings->get_translator()->get_languages();
std::ostringstream language_codes;
bool source_valid = false, target_valid = false;
@ -307,7 +318,7 @@ void bot::slashcommands::process_translate_command(dpp::cluster *bot, bot::setti
settings->add_channel(s_channel, event.command.guild_id);
settings->add_translatebot_webhook(webhook->id);
std::shared_ptr<bot::database::database> database = settings->get_database();
auto database = settings->get_database();
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();
@ -333,7 +344,7 @@ void bot::slashcommands::process_translate_command(dpp::cluster *bot, bot::setti
settings->add_target(s_target, event.command.guild_id, event.command.channel_id);
settings->add_translatebot_webhook(webhook->id);
std::shared_ptr<bot::database::database> database = settings->get_database();
auto database = settings->get_database();
database->add_channel_target(event.command.guild_id, event.command.channel_id, s_target);
database->sync();
@ -374,7 +385,7 @@ void bot::slashcommands::process_translate_webhook_add_target(bot::settings::set
settings->add_target(s_target, event.command.guild_id, event.command.channel_id);
settings->add_translatebot_webhook(webhook.id);
std::shared_ptr<bot::database::database> database = settings->get_database();
auto database = settings->get_database();
database->add_channel_target(event.command.guild_id, event.command.channel_id, s_target);
database->sync();
@ -396,7 +407,7 @@ void bot::slashcommands::process_translate_webhook_new_channel(bot::settings::se
settings->add_channel(s_channel, event.command.guild_id);
settings->add_translatebot_webhook(webhook.id);
std::shared_ptr<bot::database::database> database = settings->get_database();
auto database = settings->get_database();
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();

View file

@ -22,14 +22,6 @@
#include "translator.h"
using namespace bot::translator;
translator::translator()
{
}
translator::~translator()
{
}
const std::vector<language> translator::get_languages()
{
#ifndef NDEBUG

View file

@ -31,8 +31,8 @@ namespace bot {
class translator {
public:
explicit translator();
virtual ~translator();
explicit translator() = default;
virtual ~translator() = default;
virtual const std::vector<language> get_languages();
virtual const std::string translate(const std::string &text, const std::string &source, const std::string &target);
};