Add a Record History option in the Channel configuration form
fix #3269
This commit is contained in:
@@ -3,6 +3,8 @@ Version 6.0
|
|||||||
|
|
||||||
- The LiteSQL dependency was removed. Only libsqlite3 is now necessary
|
- The LiteSQL dependency was removed. Only libsqlite3 is now necessary
|
||||||
to work with the database.
|
to work with the database.
|
||||||
|
- The RecordHistory option can now also be configured for each IRC channel,
|
||||||
|
individually.
|
||||||
|
|
||||||
Version 5.0 - 2017-05-24
|
Version 5.0 - 2017-05-24
|
||||||
========================
|
========================
|
||||||
|
|||||||
+6
-1
@@ -358,7 +358,7 @@ History
|
|||||||
-------
|
-------
|
||||||
|
|
||||||
Public channel messages are saved into archives, inside the database, unless
|
Public channel messages are saved into archives, inside the database, unless
|
||||||
the `record_history` option is set to false for that user `Ad-hoc commands`.
|
the `record_history` option is set to false by that user (see `Ad-hoc commands`).
|
||||||
Private messages (messages that are sent directly to a nickname, not a
|
Private messages (messages that are sent directly to a nickname, not a
|
||||||
channel) are never stored in the database. When a channel is joined, biboumi
|
channel) are never stored in the database. When a channel is joined, biboumi
|
||||||
sends the `max_history_length` messages found in the database as the MUC
|
sends the `max_history_length` messages found in the database as the MUC
|
||||||
@@ -631,6 +631,11 @@ On a channel JID (e.g on the JID #test%chat.freenode.org@biboumi.example.com)
|
|||||||
the archiving of messages is enabled for this room, the client will
|
the archiving of messages is enabled for this room, the client will
|
||||||
receive the messages that where sent in this channel. This option can be
|
receive the messages that where sent in this channel. This option can be
|
||||||
used to make biboumi act as an IRC bouncer.
|
used to make biboumi act as an IRC bouncer.
|
||||||
|
* Record History: whether or not history messages should be saved in
|
||||||
|
the database, for this specific channel. If the value is “unset” (the
|
||||||
|
default), then the value configured globally is used. This option is there,
|
||||||
|
for example, to be able to enable history recording globally while disabling
|
||||||
|
it for a few specific “private” channels.
|
||||||
|
|
||||||
Raw IRC messages
|
Raw IRC messages
|
||||||
----------------
|
----------------
|
||||||
|
|||||||
@@ -20,6 +20,16 @@ struct OptionalBool
|
|||||||
this->is_set = false;
|
this->is_set = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string to_string()
|
||||||
|
{
|
||||||
|
if (this->is_set == false)
|
||||||
|
return "unset";
|
||||||
|
else if (this->value)
|
||||||
|
return "true";
|
||||||
|
else
|
||||||
|
return "false";
|
||||||
|
}
|
||||||
|
|
||||||
bool is_set{false};
|
bool is_set{false};
|
||||||
bool value{false};
|
bool value{false};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -434,6 +434,26 @@ void insert_irc_channel_configuration_form(XmlNode& node, const Jid& requester,
|
|||||||
XmlSubNode instructions(x, "instructions");
|
XmlSubNode instructions(x, "instructions");
|
||||||
instructions.set_inner("Edit the form, to configure the settings of the IRC channel "s + iid.get_local());
|
instructions.set_inner("Edit the form, to configure the settings of the IRC channel "s + iid.get_local());
|
||||||
|
|
||||||
|
XmlSubNode record_history(x, "field");
|
||||||
|
record_history["var"] = "record_history";
|
||||||
|
record_history["type"] = "list-single";
|
||||||
|
record_history["label"] = "Record history for this channel";
|
||||||
|
record_history["desc"] = "If unset, the value is the one configured globally";
|
||||||
|
|
||||||
|
{
|
||||||
|
// Value selected by default
|
||||||
|
XmlSubNode value(record_history, "value");
|
||||||
|
value.set_inner(options.col<Database::RecordHistoryOptional>().to_string());
|
||||||
|
}
|
||||||
|
// All three possible values
|
||||||
|
for (const auto& val: {"unset", "true", "false"})
|
||||||
|
{
|
||||||
|
XmlSubNode option(record_history, "option");
|
||||||
|
option["label"] = val;
|
||||||
|
XmlSubNode value(option, "value");
|
||||||
|
value.set_inner(val);
|
||||||
|
}
|
||||||
|
|
||||||
XmlSubNode encoding_out(x, "field");
|
XmlSubNode encoding_out(x, "field");
|
||||||
encoding_out["var"] = "encoding_out";
|
encoding_out["var"] = "encoding_out";
|
||||||
encoding_out["type"] = "text-single";
|
encoding_out["type"] = "text-single";
|
||||||
@@ -471,12 +491,12 @@ void insert_irc_channel_configuration_form(XmlNode& node, const Jid& requester,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureIrcChannelStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node)
|
void ConfigureIrcChannelStep2(XmppComponent& xmpp_component, AdhocSession& session, XmlNode& command_node)
|
||||||
{
|
{
|
||||||
const Jid owner(session.get_owner_jid());
|
const Jid owner(session.get_owner_jid());
|
||||||
const Jid target(session.get_target_jid());
|
const Jid target(session.get_target_jid());
|
||||||
|
|
||||||
if (handle_irc_channel_configuration_form(command_node, owner, target))
|
if (handle_irc_channel_configuration_form(xmpp_component, command_node, owner, target))
|
||||||
{
|
{
|
||||||
command_node.delete_all_children();
|
command_node.delete_all_children();
|
||||||
XmlSubNode note(command_node, "note");
|
XmlSubNode note(command_node, "note");
|
||||||
@@ -492,7 +512,7 @@ void ConfigureIrcChannelStep2(XmppComponent&, AdhocSession& session, XmlNode& co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handle_irc_channel_configuration_form(const XmlNode& node, const Jid& requester, const Jid& target)
|
bool handle_irc_channel_configuration_form(XmppComponent& xmpp_component, const XmlNode& node, const Jid& requester, const Jid& target)
|
||||||
{
|
{
|
||||||
const XmlNode* x = node.get_child("x", "jabber:x:data");
|
const XmlNode* x = node.get_child("x", "jabber:x:data");
|
||||||
if (x)
|
if (x)
|
||||||
@@ -500,7 +520,7 @@ bool handle_irc_channel_configuration_form(const XmlNode& node, const Jid& reque
|
|||||||
if (x->get_tag("type") == "submit")
|
if (x->get_tag("type") == "submit")
|
||||||
{
|
{
|
||||||
const Iid iid(target.local, {});
|
const Iid iid(target.local, {});
|
||||||
auto options = Database::get_irc_channel_options(requester.local + "@" + requester.domain,
|
auto options = Database::get_irc_channel_options(requester.bare(),
|
||||||
iid.get_server(), iid.get_local());
|
iid.get_server(), iid.get_local());
|
||||||
for (const XmlNode *field: x->get_children("field", "jabber:x:data"))
|
for (const XmlNode *field: x->get_children("field", "jabber:x:data"))
|
||||||
{
|
{
|
||||||
@@ -517,6 +537,31 @@ bool handle_irc_channel_configuration_form(const XmlNode& node, const Jid& reque
|
|||||||
else if (field->get_tag("var") == "persistent" &&
|
else if (field->get_tag("var") == "persistent" &&
|
||||||
value)
|
value)
|
||||||
options.col<Database::Persistent>() = to_bool(value->get_inner());
|
options.col<Database::Persistent>() = to_bool(value->get_inner());
|
||||||
|
else if (field->get_tag("var") == "record_history" &&
|
||||||
|
value && !value->get_inner().empty())
|
||||||
|
{
|
||||||
|
OptionalBool& database_value = options.col<Database::RecordHistoryOptional>();
|
||||||
|
if (value->get_inner() == "true")
|
||||||
|
database_value.set_value(true);
|
||||||
|
else if (value->get_inner() == "false")
|
||||||
|
database_value.set_value(false);
|
||||||
|
else
|
||||||
|
database_value.unset();
|
||||||
|
auto& biboumi_component = dynamic_cast<BiboumiComponent&>(xmpp_component);
|
||||||
|
Bridge* bridge = biboumi_component.find_user_bridge(requester.bare());
|
||||||
|
if (bridge)
|
||||||
|
{
|
||||||
|
if (database_value.is_set)
|
||||||
|
bridge->set_record_history(database_value.value);
|
||||||
|
else
|
||||||
|
{ // It is unset, we need to fetch the Global option, to
|
||||||
|
// know if it’s enabled or not
|
||||||
|
auto g_options = Database::get_global_options(requester.bare());
|
||||||
|
bridge->set_record_history(g_options.col<Database::RecordHistory>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
options.save(Database::db);
|
options.save(Database::db);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com
|
|||||||
void ConfigureIrcChannelStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
void ConfigureIrcChannelStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
||||||
void insert_irc_channel_configuration_form(XmlNode& node, const Jid& requester, const Jid& target);
|
void insert_irc_channel_configuration_form(XmlNode& node, const Jid& requester, const Jid& target);
|
||||||
void ConfigureIrcChannelStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
void ConfigureIrcChannelStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
||||||
bool handle_irc_channel_configuration_form(const XmlNode& node, const Jid& requester, const Jid& target);
|
bool handle_irc_channel_configuration_form(XmppComponent&, const XmlNode& node, const Jid& requester, const Jid& target);
|
||||||
|
|
||||||
void DisconnectUserFromServerStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
void DisconnectUserFromServerStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
||||||
void DisconnectUserFromServerStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
void DisconnectUserFromServerStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
||||||
|
|||||||
@@ -719,7 +719,7 @@ bool BiboumiComponent::handle_room_configuration_form(const XmlNode& query, cons
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
Jid requester(from);
|
Jid requester(from);
|
||||||
if (!handle_irc_channel_configuration_form(query, requester, to))
|
if (!handle_irc_channel_configuration_form(*this, query, requester, to))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Stanza iq("iq");
|
Stanza iq("iq");
|
||||||
|
|||||||
@@ -2467,6 +2467,7 @@ if __name__ == '__main__':
|
|||||||
partial(expect_stanza, ("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
|
partial(expect_stanza, ("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
|
||||||
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']",
|
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']",
|
||||||
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']",
|
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']",
|
||||||
|
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='list-single'][@var='record_history']/dataform:value[text()='unset']",
|
||||||
),
|
),
|
||||||
after = partial(save_value, "sessionid", partial(extract_attribute, "/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
|
after = partial(save_value, "sessionid", partial(extract_attribute, "/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
|
||||||
),
|
),
|
||||||
@@ -2476,6 +2477,7 @@ if __name__ == '__main__':
|
|||||||
"<field var='ports' />"
|
"<field var='ports' />"
|
||||||
"<field var='encoding_out'><value>UTF-8</value></field>"
|
"<field var='encoding_out'><value>UTF-8</value></field>"
|
||||||
"<field var='encoding_in'><value>latin-1</value></field>"
|
"<field var='encoding_in'><value>latin-1</value></field>"
|
||||||
|
"<field var='record_history'><value>true</value></field>"
|
||||||
"</x></command></iq>"),
|
"</x></command></iq>"),
|
||||||
partial(expect_stanza, "/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
|
partial(expect_stanza, "/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
|
||||||
|
|
||||||
@@ -2484,6 +2486,7 @@ if __name__ == '__main__':
|
|||||||
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure the IRC channel #foo on server irc.localhost']",
|
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure the IRC channel #foo on server irc.localhost']",
|
||||||
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']/dataform:value[text()='latin-1']",
|
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']/dataform:value[text()='latin-1']",
|
||||||
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']/dataform:value[text()='UTF-8']",
|
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']/dataform:value[text()='UTF-8']",
|
||||||
|
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='list-single'][@var='record_history']/dataform:value[text()='true']",
|
||||||
"/iq/commands:command/commands:actions/commands:next",
|
"/iq/commands:command/commands:actions/commands:next",
|
||||||
),
|
),
|
||||||
after = partial(save_value, "sessionid", partial(extract_attribute, "/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
|
after = partial(save_value, "sessionid", partial(extract_attribute, "/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
|
||||||
|
|||||||
Reference in New Issue
Block a user