diff options
-rw-r--r-- | database/database.xml | 10 | ||||
-rw-r--r-- | src/database/database.cpp | 36 | ||||
-rw-r--r-- | src/database/database.hpp | 5 | ||||
-rw-r--r-- | src/xmpp/biboumi_adhoc_commands.cpp | 74 | ||||
-rw-r--r-- | src/xmpp/biboumi_adhoc_commands.hpp | 5 | ||||
-rw-r--r-- | src/xmpp/biboumi_component.cpp | 8 |
6 files changed, 126 insertions, 12 deletions
diff --git a/database/database.xml b/database/database.xml index fc67caf..277d03f 100644 --- a/database/database.xml +++ b/database/database.xml @@ -2,6 +2,12 @@ <!DOCTYPE database SYSTEM "litesql.dtd"> <database name="BibouDB" namespace="db"> + <object name="GlobalOptions"> + <field name="owner" type="string" length="3071"/> + + <field name="maxHistoryLength" type="integer"/> + </object> + <object name="IrcServerOptions"> <field name="owner" type="string" length="3071"/> <field name="server" type="string" length="3071"/> @@ -18,6 +24,8 @@ <field name="encodingOut" type="string" default="ISO-8859-1"/> <field name="encodingIn" type="string" default="ISO-8859-1"/> + <field name="maxHistoryLength" type="integer"/> + <index unique="true"> <indexfield name="owner"/> <indexfield name="server"/> @@ -32,6 +40,8 @@ <field name="encodingOut" type="string"/> <field name="encodingIn" type="string"/> + <field name="maxHistoryLength" type="integer"/> + <index unique="true"> <indexfield name="owner"/> <indexfield name="server"/> diff --git a/src/database/database.cpp b/src/database/database.cpp index 3891f41..acf57d1 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -31,6 +31,19 @@ void Database::set_verbose(const bool val) Database::db->verbose = val; } +db::GlobalOptions Database::get_global_options(const std::string& owner) +{ + try { + auto options = litesql::select<db::GlobalOptions>(*Database::db, + db::GlobalOptions::Owner == owner).one(); + return options; + } catch (const litesql::NotFound& e) { + db::GlobalOptions options(*Database::db); + options.owner = owner; + return options; + } +} + db::IrcServerOptions Database::get_irc_server_options(const std::string& owner, const std::string& server) { @@ -79,6 +92,29 @@ db::IrcChannelOptions Database::get_irc_channel_options_with_server_default(cons coptions.encodingOut = get_first_non_empty(coptions.encodingOut.value(), soptions.encodingOut.value()); + coptions.maxHistoryLength = get_first_non_empty(coptions.maxHistoryLength.value(), + soptions.maxHistoryLength.value()); + + return coptions; +} + +db::IrcChannelOptions Database::get_irc_channel_options_with_server_and_global_default(const std::string& owner, + const std::string& server, + const std::string& channel) +{ + auto coptions = Database::get_irc_channel_options(owner, server, channel); + auto soptions = Database::get_irc_server_options(owner, server); + auto goptions = Database::get_global_options(owner); + + coptions.encodingIn = get_first_non_empty(coptions.encodingIn.value(), + soptions.encodingIn.value()); + coptions.encodingOut = get_first_non_empty(coptions.encodingOut.value(), + soptions.encodingOut.value()); + + coptions.maxHistoryLength = get_first_non_empty(coptions.maxHistoryLength.value(), + soptions.maxHistoryLength.value(), + goptions.maxHistoryLength.value()); + return coptions; } diff --git a/src/database/database.hpp b/src/database/database.hpp index b11332e..d1be2fd 100644 --- a/src/database/database.hpp +++ b/src/database/database.hpp @@ -36,6 +36,7 @@ public: * Return the object from the db. Create it beforehand (with all default * values) if it is not already present. */ + static db::GlobalOptions get_global_options(const std::string& owner); static db::IrcServerOptions get_irc_server_options(const std::string& owner, const std::string& server); static db::IrcChannelOptions get_irc_channel_options(const std::string& owner, @@ -44,7 +45,9 @@ public: static db::IrcChannelOptions get_irc_channel_options_with_server_default(const std::string& owner, const std::string& server, const std::string& channel); - + static db::IrcChannelOptions get_irc_channel_options_with_server_and_global_default(const std::string& owner, + const std::string& server, + const std::string& channel); static void store_muc_message(const std::string& owner, const Iid& iid, time_point date, const std::string& body, const std::string& nick); diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp index b14081f..2050edf 100644 --- a/src/xmpp/biboumi_adhoc_commands.cpp +++ b/src/xmpp/biboumi_adhoc_commands.cpp @@ -11,10 +11,6 @@ #include <database/database.hpp> #endif -#include <louloulibs.h> - -#include <algorithm> - using namespace std::string_literals; void DisconnectUserStep1(XmppComponent& xmpp_component, AdhocSession&, XmlNode& command_node) @@ -114,6 +110,72 @@ void DisconnectUserStep2(XmppComponent& xmpp_component, AdhocSession& session, X } #ifdef USE_DATABASE + +void ConfigureGlobalStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node) +{ + const Jid owner(session.get_owner_jid()); + const Jid target(session.get_target_jid()); + + auto options = Database::get_global_options(owner.bare()); + + XmlNode x("jabber:x:data:x"); + x["type"] = "form"; + XmlNode title("title"); + title.set_inner("Configure some global default settings."); + x.add_child(std::move(title)); + XmlNode instructions("instructions"); + instructions.set_inner("Edit the form, to configure your global settings for the component."); + x.add_child(std::move(instructions)); + + XmlNode required("required"); + + XmlNode max_histo_length("field"); + max_histo_length["var"] = "max_history_length"; + max_histo_length["type"] = "text-single"; + max_histo_length["label"] = "Max history length"; + max_histo_length["desc"] = "The maximum number of lines in the history that the server sends when joining a channel"; + + XmlNode max_histo_length_value("value"); + max_histo_length_value.set_inner(std::to_string(options.maxHistoryLength.value())); + max_histo_length.add_child(std::move(max_histo_length_value)); + x.add_child(std::move(max_histo_length)); + + command_node.add_child(std::move(x)); +} + +void ConfigureGlobalStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node) +{ + const XmlNode* x = command_node.get_child("x", "jabber:x:data"); + if (x) + { + const Jid owner(session.get_owner_jid()); + auto options = Database::get_global_options(owner.bare()); + for (const XmlNode* field: x->get_children("field", "jabber:x:data")) + { + const XmlNode* value = field->get_child("value", "jabber:x:data"); + + if (field->get_tag("var") == "max_history_length" && + value && !value->get_inner().empty()) + options.maxHistoryLength = value->get_inner(); + } + + options.update(); + + command_node.delete_all_children(); + XmlNode note("note"); + note["type"] = "info"; + note.set_inner("Configuration successfully applied."); + command_node.add_child(std::move(note)); + return; + } + XmlNode error(ADHOC_NS":error"); + error["type"] = "modify"; + XmlNode condition(STANZA_NS":bad-request"); + error.add_child(std::move(condition)); + command_node.add_child(std::move(error)); + session.terminate(); +} + void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node) { const Jid owner(session.get_owner_jid()); @@ -315,7 +377,7 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com } else if (field->get_tag("var") == "verify_cert" && value - && !value->get_inner().empty()) + && !value->get_inner().empty()) { auto val = to_bool(value->get_inner()); options.verifyCert = val; @@ -442,7 +504,7 @@ void ConfigureIrcChannelStep2(XmppComponent&, AdhocSession& session, XmlNode& co const XmlNode* value = field->get_child("value", "jabber:x:data"); if (field->get_tag("var") == "encoding_out" && - value && !value->get_inner().empty()) + value && !value->get_inner().empty()) options.encodingOut = value->get_inner(); else if (field->get_tag("var") == "encoding_in" && diff --git a/src/xmpp/biboumi_adhoc_commands.hpp b/src/xmpp/biboumi_adhoc_commands.hpp index 2763a9f..7be5509 100644 --- a/src/xmpp/biboumi_adhoc_commands.hpp +++ b/src/xmpp/biboumi_adhoc_commands.hpp @@ -10,6 +10,9 @@ class XmppComponent; void DisconnectUserStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node); void DisconnectUserStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node); +void ConfigureGlobalStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node); +void ConfigureGlobalStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node); + void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node); void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node); @@ -19,5 +22,3 @@ void ConfigureIrcChannelStep2(XmppComponent&, AdhocSession& session, XmlNode& co void DisconnectUserFromServerStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node); void DisconnectUserFromServerStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node); void DisconnectUserFromServerStep3(XmppComponent&, AdhocSession& session, XmlNode& command_node); - - diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index 5c52494..9acccdb 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -63,11 +63,13 @@ BiboumiComponent::BiboumiComponent(std::shared_ptr<Poller> poller, const std::st #ifdef USE_DATABASE AdhocCommand configure_server_command({&ConfigureIrcServerStep1, &ConfigureIrcServerStep2}, "Configure a few settings for that IRC server", false); + AdhocCommand configure_global_command({&ConfigureGlobalStep1, &ConfigureGlobalStep2}, "Configure a few settings", false); if (!Config::get("fixed_irc_server", "").empty()) - { this->adhoc_commands_handler.get_commands().emplace(std::make_pair("configure", - configure_server_command)); - } + configure_server_command)); + else + this->adhoc_commands_handler.get_commands().emplace(std::make_pair("configure", + configure_global_command)); #endif this->irc_server_adhoc_commands_handler.get_commands() = { |