~singpolyma/biboumi

6776b827d243ec0e018eac8233c5df402030640e — louiz’ 7 years ago 992fa93
Add a global configure ad-hoc command, with max history length
M database/database.xml => database/database.xml +10 -0
@@ 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"/>

M src/database/database.cpp => src/database/database.cpp +36 -0
@@ 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;
}


M src/database/database.hpp => src/database/database.hpp +4 -1
@@ 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);


M src/xmpp/biboumi_adhoc_commands.cpp => src/xmpp/biboumi_adhoc_commands.cpp +68 -6
@@ 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" &&

M src/xmpp/biboumi_adhoc_commands.hpp => src/xmpp/biboumi_adhoc_commands.hpp +3 -2
@@ 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);



M src/xmpp/biboumi_component.cpp => src/xmpp/biboumi_component.cpp +5 -3
@@ 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() = {