1
0
mirror of https://github.com/anope/anope.git synced 2026-07-03 00:23:12 +02:00

Rework the InfoFormatter/ListFormatter APIs and move to textproc.

This commit is contained in:
Sadie Powell
2025-09-19 11:36:57 +01:00
parent 3b2d798e76
commit 59bb9d3d06
34 changed files with 76 additions and 268 deletions
-32
View File
@@ -57,35 +57,3 @@ public:
*/
virtual bool InvalidRange(const Anope::string &list);
};
/** This class handles formatting LIST/VIEW replies.
*/
class CoreExport ListFormatter final
{
public:
typedef std::map<Anope::string, Anope::string> ListEntry;
private:
NickCore *nc;
std::vector<Anope::string> columns;
std::vector<ListEntry> entries;
public:
ListFormatter(NickCore *nc);
ListFormatter &AddColumn(const Anope::string &name);
void AddEntry(const ListEntry &entry);
bool IsEmpty() const;
void Process(std::vector<Anope::string> &);
};
/** This class handles formatting INFO replies
*/
class CoreExport InfoFormatter final
{
NickCore *nc;
std::vector<std::pair<Anope::string, Anope::string> > replies;
unsigned longest = 0;
public:
InfoFormatter(NickCore *nc);
void Process(std::vector<Anope::string> &);
Anope::string &operator[](const Anope::string &key);
void AddOption(const Anope::string &opt);
};
+31
View File
@@ -109,6 +109,20 @@ public:
void SendTo(CommandSource &source);
};
class CoreExport InfoFormatter final
{
private:
size_t longest = 0;
NickCore *nc;
std::vector<std::pair<Anope::string, Anope::string> > replies;
public:
InfoFormatter(NickCore *nc);
Anope::string &operator[](const Anope::string &key);
void AddOption(const Anope::string &opt);
void SendTo(CommandSource &source);
};
class CoreExport LineWrapper final
{
private:
@@ -121,3 +135,20 @@ public:
bool GetLine(Anope::string &out);
};
class CoreExport ListFormatter final
{
public:
using ListEntry = std::map<Anope::string, Anope::string>;
private:
std::vector<Anope::string> columns;
std::vector<ListEntry> entries;
NickCore *nc;
public:
ListFormatter(NickCore *nc);
ListFormatter &AddColumn(const Anope::string &name);
void AddEntry(const ListEntry &entry);
bool IsEmpty() const;
void SendTo(CommandSource &source);
};
+1 -7
View File
@@ -305,14 +305,8 @@ private:
source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
else
{
std::vector<Anope::string> replies;
list.Process(replies);
source.Reply(_("Bad words list for %s:"), ci->name.c_str());
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(_("End of bad words list."));
}
}
+1 -7
View File
@@ -66,9 +66,6 @@ public:
}
}
std::vector<Anope::string> replies;
list.Process(replies);
if (!count)
{
source.Reply(_(
@@ -79,10 +76,7 @@ public:
else
{
source.Reply(_("Bot list:"));
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(_("%d bots available."), count);
}
}
+2 -12
View File
@@ -58,12 +58,7 @@ public:
info[_("Used on")] = Anope::Format(Language::Translate(source.nc, bi->GetChannelCount(), N_("%u channel", "%u channels")), bi->GetChannelCount());
FOREACH_MOD(OnBotInfo, (source, bi, ci, info));
std::vector<Anope::string> replies;
info.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
info.SendTo(source);
if (source.HasPriv("botserv/administration"))
{
@@ -89,12 +84,7 @@ public:
Anope::string disabled = Language::Translate(source.nc, _("Disabled"));
FOREACH_MOD(OnBotInfo, (source, bi, ci, info));
std::vector<Anope::string> replies;
info.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
info.SendTo(source);
}
else
source.Reply(_("\002%s\002 is not a valid bot or registered channel."), query.c_str());
+3 -17
View File
@@ -435,14 +435,8 @@ private:
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
else
{
std::vector<Anope::string> replies;
list.Process(replies);
source.Reply(_("Access list for %s:"), ci->name.c_str());
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(_("End of access list"));
}
@@ -744,11 +738,7 @@ class CommandCSLevels final
list.AddEntry(entry);
}
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
void DoReset(CommandSource &source, ChannelInfo *ci)
@@ -834,11 +824,7 @@ public:
list.AddEntry(entry);
}
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
else
{
+1 -7
View File
@@ -378,14 +378,8 @@ class CommandCSAKick final
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
else
{
std::vector<Anope::string> replies;
list.Process(replies);
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(_("End of autokick list"));
}
}
+1 -5
View File
@@ -140,11 +140,7 @@ private:
list.AddEntry(entry);
}
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(_("End of entry message list."));
}
+1 -5
View File
@@ -348,12 +348,8 @@ class CommandCSFlags final
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
else
{
std::vector<Anope::string> replies;
list.Process(replies);
source.Reply(_("Flags list for %s"), ci->name.c_str());
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
if (count == ci->GetAccessCount())
source.Reply(_("End of access list."));
else
+1 -6
View File
@@ -62,12 +62,7 @@ public:
}
FOREACH_MOD(OnChanInfo, (source, ci, info, show_all));
std::vector<Anope::string> replies;
info.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
info.SendTo(source);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+1 -6
View File
@@ -122,12 +122,7 @@ public:
}
}
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(_("End of list - %d/%d matches shown."), nchans > listmax ? listmax : nchans, nchans);
}
+1 -6
View File
@@ -154,12 +154,7 @@ public:
}
source.Reply(_("Log list for %s:"), ci->name.c_str());
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
}
else if (params.size() > 2)
+1 -6
View File
@@ -466,12 +466,7 @@ class CommandCSMode final
}
source.Reply(_("Mode locks for %s:"), ci->name.c_str());
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
}
else
+1 -5
View File
@@ -453,12 +453,8 @@ private:
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
else
{
std::vector<Anope::string> replies;
list.Process(replies);
source.Reply(_("%s list for %s"), source.command.nobreak().c_str(), ci->name.c_str());
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
}
+1 -5
View File
@@ -121,11 +121,7 @@ private:
entry["Message"] = (*q)[i];
list.AddEntry(entry);
}
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
public:
+1 -5
View File
@@ -112,11 +112,7 @@ public:
source.Reply(_("Displayed all records (count: \002%d\002)."), display_counter);
}
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+1 -6
View File
@@ -468,12 +468,7 @@ public:
++counter;
}
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(_("Displayed \002%d\002 records (\002%d\002 total)."), display_counter, counter);
}
+1 -6
View File
@@ -85,12 +85,7 @@ public:
}
source.Reply(_("Memo ignore list:"));
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
}
else
+1 -5
View File
@@ -127,12 +127,8 @@ public:
}
}
std::vector<Anope::string> replies;
list.Process(replies);
source.Reply(_("Memos for %s:"), ci ? ci->name.c_str() : source.GetNick().c_str());
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
return;
}
+1 -6
View File
@@ -124,12 +124,7 @@ class CommandNSAJoin final
}
source.Reply(_("%s's auto join list:"), nc->display.c_str());
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
}
+1 -7
View File
@@ -87,9 +87,6 @@ public:
list.AddEntry(entry);
}
std::vector<Anope::string> replies;
list.Process(replies);
if (!chan_count)
{
source.Reply(_("\002%s\002 has no access in any channels."), nc->display.c_str());
@@ -97,10 +94,7 @@ public:
else
{
source.Reply(_("Channels that \002%s\002 has access on:"), nc->display.c_str());
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(_("End of list - %d channels shown."), chan_count);
}
}
+1 -6
View File
@@ -354,12 +354,7 @@ public:
}
source.Reply(!nick.empty() ? _("List of nicknames belonging to \002%s\002:") : _("List of nicknames belonging to your account:"), nc->display.c_str());
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(nc->aliases->size(), N_("%zu nickname in the account.", "%zu nicknames in the account."), nc->aliases->size());
}
+1 -6
View File
@@ -136,12 +136,7 @@ public:
}
FOREACH_MOD(OnNickInfo, (source, na, info, show_hidden));
std::vector<Anope::string> replies;
info.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
info.SendTo(source);
}
}
+1 -7
View File
@@ -120,13 +120,7 @@ public:
}
source.Reply(_("List of entries matching \002%s\002:"), pattern.c_str());
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(_("End of list - %d/%d matches shown."), nnicks > listmax ? listmax : nnicks, nnicks);
return;
}
+1 -7
View File
@@ -337,13 +337,7 @@ private:
else
{
source.Reply(_("Current AKILL list:"));
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(_("End of AKILL list."));
}
}
+2 -15
View File
@@ -71,14 +71,8 @@ public:
lflist.AddEntry(entry);
}
std::vector<Anope::string> replies;
lflist.Process(replies);
source.Reply(_("%s settings:"), block.GetName().c_str());
for (const auto &reply : replies)
source.Reply(reply);
lflist.SendTo(source);
source.Reply(" ");
}
@@ -103,15 +97,8 @@ public:
lflist.AddEntry(entry);
}
}
std::vector<Anope::string> replies;
lflist.Process(replies);
source.Reply(_("Module settings:"));
for (const auto &reply : replies)
source.Reply(reply);
lflist.SendTo(source);
source.Reply(_("End of configuration."));
}
else
+2 -8
View File
@@ -269,9 +269,7 @@ class CommandOSDNS final
lf.AddEntry(entry);
}
std::vector<Anope::string> replies;
lf.Process(replies);
lf.SendTo(source);
if (!zones->empty())
{
@@ -295,12 +293,8 @@ class CommandOSDNS final
lf2.AddEntry(entry);
}
lf2.Process(replies);
lf2.SendTo(source);
}
for (const auto &reply : replies)
source.Reply(reply);
}
void AddZone(CommandSource &source, const std::vector<Anope::string> &params)
+1 -6
View File
@@ -430,12 +430,7 @@ public:
else
{
source.Reply(_("Forbid list:"));
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
if (shown >= forbids.size())
source.Reply(_("End of forbid list."));
+1 -6
View File
@@ -292,12 +292,7 @@ private:
}
source.Reply(_("Services ignore list:"));
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
}
+2 -12
View File
@@ -96,12 +96,7 @@ public:
}
}
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(_("End of channel list. \002%u\002 channels shown."), count);
}
@@ -243,12 +238,7 @@ public:
}
}
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
source.Reply(_("End of users list. \002%u\002 users shown."), count);
return;
}
+1 -7
View File
@@ -217,13 +217,7 @@ protected:
}
source.Reply(msgs[MSG_LIST_HEADER]);
std::vector<Anope::string> replies;
lflist.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
lflist.SendTo(source);
source.Reply(_("End of news list."));
}
+2 -13
View File
@@ -249,13 +249,7 @@ private:
}
source.Reply(_("Hosts with at least \002%d\002 sessions:"), mincount);
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
return;
@@ -534,12 +528,7 @@ private:
else
{
source.Reply(_("Current Session Limit Exception list:"));
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
}
+1 -6
View File
@@ -191,12 +191,7 @@ private:
else
{
source.Reply(_("Current %s list:"), source.command.nobreak().c_str());
std::vector<Anope::string> replies;
list.Process(replies);
for (const auto &reply : replies)
source.Reply(reply);
list.SendTo(source);
}
}
+7 -8
View File
@@ -141,7 +141,7 @@ bool ListFormatter::IsEmpty() const
return this->entries.empty();
}
void ListFormatter::Process(std::vector<Anope::string> &buffer)
void ListFormatter::SendTo(CommandSource &source)
{
std::vector<Anope::string> tcolumns;
std::map<Anope::string, size_t> lengths;
@@ -181,7 +181,7 @@ void ListFormatter::Process(std::vector<Anope::string> &buffer)
{
if (breaks.count(this->columns[i]))
{
buffer.push_back(s);
source.Reply(s);
s = " ";
}
else if (!s.empty())
@@ -191,7 +191,7 @@ void ListFormatter::Process(std::vector<Anope::string> &buffer)
for (unsigned j = tcolumns[i].length(); j < lengths[this->columns[i]]; ++j)
s += " ";
}
buffer.push_back(s);
source.Reply(s);
}
for (auto &entry : this->entries)
@@ -201,7 +201,7 @@ void ListFormatter::Process(std::vector<Anope::string> &buffer)
{
if (breaks.count(this->columns[j]))
{
buffer.push_back(s);
source.Reply(s);
s = " ";
}
else if (!s.empty())
@@ -211,7 +211,7 @@ void ListFormatter::Process(std::vector<Anope::string> &buffer)
for (unsigned k = entry[this->columns[j]].length(); k < lengths[this->columns[j]]; ++k)
s += " ";
}
buffer.push_back(s);
source.Reply(s);
}
}
@@ -219,16 +219,15 @@ InfoFormatter::InfoFormatter(NickCore *acc) : nc(acc)
{
}
void InfoFormatter::Process(std::vector<Anope::string> &buffer)
void InfoFormatter::SendTo(CommandSource &source)
{
buffer.clear();
for (const auto &[key, value] : this->replies)
{
auto line = key;
line += ": ";
line += Anope::string(longest - key.utf8length(), ' ');
line += Language::Translate(this->nc, value.c_str());
buffer.push_back(line);
source.Reply(line);
}
}