diff options
Diffstat (limited to 'modules/memoserv/read.cpp')
-rw-r--r-- | modules/memoserv/read.cpp | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/modules/memoserv/read.cpp b/modules/memoserv/read.cpp new file mode 100644 index 000000000..60fc98b0c --- /dev/null +++ b/modules/memoserv/read.cpp @@ -0,0 +1,226 @@ +/* + * Anope IRC Services + * + * Copyright (C) 2003-2017 Anope Team <team@anope.org> + * + * This file is part of Anope. Anope is free software; you can + * redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software + * Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see see <http://www.gnu.org/licenses/>. + */ + +#include "module.h" +#include "modules/memoserv.h" + +static void rsend_notify(CommandSource &source, MemoServ::MemoInfo *mi, MemoServ::Memo *m, const Anope::string &targ) +{ + /* Only send receipt if memos are allowed */ + if (MemoServ::service && !Anope::ReadOnly) + { + /* Get nick alias for sender */ + NickServ::Nick *na = NickServ::FindNick(m->GetSender()); + + if (!na) + return; + + /* Get nick core for sender */ + NickServ::Account *nc = na->GetAccount(); + + if (!nc) + return; + + /* Text of the memo varies if the recipient was a + nick or channel */ + Anope::string text = Anope::printf(Language::Translate(na->GetAccount(), _("\002[auto-memo]\002 The memo you sent to \002%s\002 has been viewed.")), targ.c_str()); + + /* Send notification */ + MemoServ::service->Send(source.GetNick(), m->GetSender(), text, true); + + /* Notify recipient of the memo that a notification has + been sent to the sender */ + source.Reply(_("A notification memo has been sent to \002{0}\002 informing him/her you have read his/her memo."), nc->GetDisplay()); + } + + /* Remove receipt flag from the original memo */ + m->SetReceipt(false); +} + +class CommandMSRead : public Command +{ + static void DoRead(CommandSource &source, MemoServ::MemoInfo *mi, ChanServ::Channel *ci, unsigned index) + { + MemoServ::Memo *m = mi->GetMemo(index); + if (!m) + return; + + if (ci) + source.Reply(_("Memo \002{0}\002 from \002{1}\002 (\002{2}\002)."), index + 1, m->GetSender(), Anope::strftime(m->GetTime(), source.GetAccount())); + else + source.Reply(_("Memo \002{0}\002 from \002{1}\002 (\002{2}\002)."), index + 1, m->GetSender(), Anope::strftime(m->GetTime(), source.GetAccount())); + + ServiceBot *bi; + Anope::string cmd; + if (Command::FindCommandFromService("memoserv/del", bi, cmd)) + { + if (ci) + source.Reply(_("To delete, use \002{0}{1} {2} {3} {4}\002"), Config->StrictPrivmsg, bi->nick, cmd, ci->GetName(), index + 1); + else + source.Reply(_("To delete, use \002{0}{1} {2} {3}\002"), Config->StrictPrivmsg, bi->nick, cmd, index + 1); + } + + source.Reply(m->GetText()); + m->SetUnread(false); + + /* Check if a receipt notification was requested */ + if (m->GetReceipt()) + rsend_notify(source, mi, m, ci ? ci->GetName() : source.GetNick()); + } + + public: + CommandMSRead(Module *creator) : Command(creator, "memoserv/read", 1, 2) + { + this->SetDesc(_("Read a memo or memos")); + this->SetSyntax(_("[\037channel\037] {\037num\037 | \037list\037 | LAST | NEW | ALL}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override + { + MemoServ::MemoInfo *mi; + ChanServ::Channel *ci = NULL; + Anope::string numstr = params[0], chan; + + if (!numstr.empty() && numstr[0] == '#') + { + chan = numstr; + numstr = params.size() > 1 ? params[1] : ""; + + ci = ChanServ::Find(chan); + if (!ci) + { + source.Reply(_("Channel \002{0}\002 isn't registered."), chan); + return; + } + + if (!source.AccessFor(ci).HasPriv("MEMO")) + { + source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName()); + return; + } + + mi = ci->GetMemos(); + } + else + { + mi = source.nc->GetMemos(); + } + + if (numstr.empty() || (!numstr.equals_ci("LAST") && !numstr.equals_ci("NEW") && !numstr.equals_ci("ALL") && numstr.find_first_not_of("0123456789.,-") != Anope::string::npos)) + { + this->OnSyntaxError(source, numstr); + return; + } + + if (!mi) + return; + + auto memos = mi->GetMemos(); + + if (memos.empty()) + { + if (!chan.empty()) + source.Reply(_("\002{0}\002 has no memos."), chan); + else + source.Reply(_("You have no memos.")); + return; + } + + int i, end; + + if (numstr.equals_ci("NEW")) + { + int readcount = 0; + for (i = 0, end = memos.size(); i < end; ++i) + if (mi->GetMemo(i)->GetUnread()) + { + DoRead(source, mi, ci, i); + ++readcount; + } + if (!readcount) + { + if (!chan.empty()) + source.Reply(_("\002{0}\002 has no new memos."), chan); + else + source.Reply(_("You have no new memos.")); + } + } + else if (numstr.equals_ci("LAST")) + { + for (i = 0, end = memos.size() - 1; i < end; ++i); + DoRead(source, mi, ci, i); + } + else if (numstr.equals_ci("ALL")) + { + for (i = 0, end = memos.size(); i < end; ++i) + { + DoRead(source, mi, ci, i); + } + } + else /* number[s] */ + { + bool shown = false; + + NumberList(numstr, false, + [&](unsigned int number) + { + if (!number || number > memos.size()) + return; + + shown = true; + DoRead(source, mi, ci, number - 1); + }, + []{}); + + if (!shown) + source.Reply(_("No memos to display.")); + } + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) override + { + source.Reply(_("Sends you the text of the memos specified." + " If LAST is given, sends you the memo you most recently received." + " If NEW is given, sends you all of your new memos." + " If ALL is given, sends you all of your memos." + " Otherwise, sends you memo number \037num\037." + " You can also give a list of numbers, as in the example:\n" + "\n" + "Example:\n" + "\n" + " {0} 2-5,7-9\n" + " Displays memos numbered 2 through 5 and 7 through 9."), + source.GetCommand()); + return true; + } +}; + +class MSRead : public Module +{ + CommandMSRead commandmsread; + + public: + MSRead(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) + , commandmsread(this) + { + + } +}; + +MODULE_INIT(MSRead) |