anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

ms_list.cpp (4216B)

      1 /* MemoServ core functions
      2  *
      3  * (C) 2003-2022 Anope Team
      4  * Contact us at team@anope.org
      5  *
      6  * Please read COPYING and README for further details.
      7  *
      8  * Based on the original code of Epona by Lara.
      9  * Based on the original code of Services by Andy Church.
     10  */
     11 
     12 #include "module.h"
     13 
     14 class CommandMSList : public Command
     15 {
     16  public:
     17 	CommandMSList(Module *creator) : Command(creator, "memoserv/list", 0, 2)
     18 	{
     19 		this->SetDesc(_("List your memos"));
     20 		this->SetSyntax(_("[\037channel\037] [\037list\037 | NEW]"));
     21 	}
     22 
     23 	void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
     24 	{
     25 
     26 		Anope::string param = !params.empty() ? params[0] : "", chan;
     27 		ChannelInfo *ci = NULL;
     28 		const MemoInfo *mi;
     29 
     30 		if (!param.empty() && param[0] == '#')
     31 		{
     32 			chan = param;
     33 			param = params.size() > 1 ? params[1] : "";
     34 
     35 			ci = ChannelInfo::Find(chan);
     36 			if (!ci)
     37 			{
     38 				source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
     39 				return;
     40 			}
     41 			else if (!source.AccessFor(ci).HasPriv("MEMO"))
     42 			{
     43 				source.Reply(ACCESS_DENIED);
     44 				return;
     45 			}
     46 			mi = &ci->memos;
     47 		}
     48 		else
     49 			mi = &source.nc->memos;
     50 
     51 		if (!param.empty() && !isdigit(param[0]) && !param.equals_ci("NEW"))
     52 			this->OnSyntaxError(source, param);
     53 		else if (!mi->memos->size())
     54 		{
     55 			if (!chan.empty())
     56 				source.Reply(MEMO_X_HAS_NO_MEMOS, chan.c_str());
     57 			else
     58 				source.Reply(MEMO_HAVE_NO_MEMOS);
     59 		}
     60 		else
     61 		{
     62 			ListFormatter list(source.GetAccount());
     63 
     64 			list.AddColumn(_("Number")).AddColumn(_("Sender")).AddColumn(_("Date/Time"));
     65 
     66 			if (!param.empty() && isdigit(param[0]))
     67 			{
     68 				class MemoListCallback : public NumberList
     69 				{
     70 					ListFormatter &list;
     71 					CommandSource &source;
     72 					const MemoInfo *mi;
     73 				 public:
     74 					MemoListCallback(ListFormatter &_list, CommandSource &_source, const MemoInfo *_mi, const Anope::string &numlist) : NumberList(numlist, false), list(_list), source(_source), mi(_mi)
     75 					{
     76 					}
     77 
     78 					void HandleNumber(unsigned number) anope_override
     79 					{
     80 						if (!number || number > mi->memos->size())
     81 							return;
     82 
     83 						const Memo *m = mi->GetMemo(number - 1);
     84 
     85 						ListFormatter::ListEntry entry;
     86 						entry["Number"] = (m->unread ? "* " : "  ") + stringify(number);
     87 						entry["Sender"] = m->sender;
     88 						entry["Date/Time"] = Anope::strftime(m->time, source.GetAccount());
     89 						this->list.AddEntry(entry);
     90 					}
     91 				}
     92 				mlc(list, source, mi, param);
     93 				mlc.Process();
     94 			}
     95 			else
     96 			{
     97 				if (!param.empty())
     98 				{
     99 					unsigned i, end;
    100 					for (i = 0, end = mi->memos->size(); i < end; ++i)
    101 						if (mi->GetMemo(i)->unread)
    102 							break;
    103 					if (i == end)
    104 					{
    105 						if (!chan.empty())
    106 							source.Reply(MEMO_X_HAS_NO_NEW_MEMOS, chan.c_str());
    107 						else
    108 							source.Reply(MEMO_HAVE_NO_NEW_MEMOS);
    109 						return;
    110 					}
    111 				}
    112 
    113 				for (unsigned i = 0, end = mi->memos->size(); i < end; ++i)
    114 				{
    115 					if (!param.empty() && !mi->GetMemo(i)->unread)
    116 						continue;
    117 
    118 					const Memo *m = mi->GetMemo(i);
    119 
    120 					ListFormatter::ListEntry entry;
    121 					entry["Number"] = (m->unread ? "* " : "  ") + stringify(i + 1);
    122 					entry["Sender"] = m->sender;
    123 					entry["Date/Time"] = Anope::strftime(m->time, source.GetAccount());
    124 					list.AddEntry(entry);
    125 				}
    126 			}
    127 
    128 			std::vector<Anope::string> replies;
    129 			list.Process(replies);
    130 
    131 			source.Reply(_("Memos for %s:"), ci ? ci->name.c_str() : source.GetNick().c_str());
    132 			for (unsigned i = 0; i < replies.size(); ++i)
    133 				source.Reply(replies[i]);
    134 		}
    135 		return;
    136 	}
    137 
    138 	bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
    139 	{
    140 		this->SendSyntax(source);
    141 		source.Reply(" ");
    142 		source.Reply(_("Lists any memos you currently have.  With \002NEW\002, lists only\n"
    143 				"new (unread) memos. Unread memos are marked with a \"*\"\n"
    144 				"to the left of the memo number. You can also specify a list\n"
    145 				"of numbers, as in the example below:\n"
    146 				"   \002LIST 2-5,7-9\002\n"
    147 				"      Lists memos numbered 2 through 5 and 7 through 9."));
    148 		return true;
    149 	}
    150 };
    151 
    152 class MSList : public Module
    153 {
    154 	CommandMSList commandmslist;
    155 
    156  public:
    157 	MSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
    158 		commandmslist(this)
    159 	{
    160 
    161 	}
    162 };
    163 
    164 MODULE_INIT(MSList)