Anope IRC Services  Version 2.0
ms_read.cpp
Go to the documentation of this file.
1 /* MemoServ core functions
2  *
3  * (C) 2003-2014 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 static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ");
15 
16 static void rsend_notify(CommandSource &source, MemoInfo *mi, Memo *m, const Anope::string &targ)
17 {
18  /* Only send receipt if memos are allowed */
20  {
21  /* Get nick alias for sender */
22  const NickAlias *na = NickAlias::Find(m->sender);
23 
24  if (!na)
25  return;
26 
27  /* Get nick core for sender */
28  const NickCore *nc = na->nc;
29 
30  if (!nc)
31  return;
32 
33  /* Text of the memo varies if the recepient was a
34  nick or channel */
35  Anope::string text = Anope::printf(Language::Translate(na->nc, _("\002[auto-memo]\002 The memo you sent to %s has been viewed.")), targ.c_str());
36 
37  /* Send notification */
38  MemoServService->Send(source.GetNick(), m->sender, text, true);
39 
40  /* Notify recepient of the memo that a notification has
41  been sent to the sender */
42  source.Reply(_("A notification memo has been sent to %s informing him/her you have\n"
43  "read his/her memo."), nc->display.c_str());
44  }
45 
46  /* Remove receipt flag from the original memo */
47  m->receipt = false;
48 }
49 
51 {
54  const ChannelInfo *ci;
55  public:
56  MemoListCallback(CommandSource &_source, MemoInfo *_mi, const ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), source(_source), mi(_mi), ci(_ci)
57  {
58  }
59 
60  void HandleNumber(unsigned number) anope_override
61  {
62  if (!number || number > mi->memos->size())
63  return;
64 
65  MemoListCallback::DoRead(source, mi, ci, number - 1);
66  }
67 
68  static void DoRead(CommandSource &source, MemoInfo *mi, const ChannelInfo *ci, unsigned index)
69  {
70  Memo *m = mi->GetMemo(index);
71  if (!m)
72  return;
73 
74  if (ci)
75  source.Reply(_("Memo %d from %s (%s)."), index + 1, m->sender.c_str(), Anope::strftime(m->time, source.GetAccount()).c_str());
76  else
77  source.Reply(_("Memo %d from %s (%s)."), index + 1, m->sender.c_str(), Anope::strftime(m->time, source.GetAccount()).c_str());
78 
79  BotInfo *bi;
80  Anope::string cmd;
81  if (Command::FindCommandFromService("memoserv/del", bi, cmd))
82  {
83  if (ci)
84  source.Reply(_("To delete, type: \002%s%s %s %s %d\002"), Config->StrictPrivmsg.c_str(), bi->nick.c_str(), cmd.c_str(), ci->name.c_str(), index + 1);
85  else
86  source.Reply(_("To delete, type: \002%s%s %s %d\002"), Config->StrictPrivmsg.c_str(), bi->nick.c_str(), cmd.c_str(), index + 1);
87  }
88 
89  source.Reply("%s", m->text.c_str());
90  m->unread = false;
91 
92  /* Check if a receipt notification was requested */
93  if (m->receipt)
94  rsend_notify(source, mi, m, ci ? ci->name : source.GetNick());
95  }
96 };
97 
98 class CommandMSRead : public Command
99 {
100  public:
101  CommandMSRead(Module *creator) : Command(creator, "memoserv/read", 1, 2)
102  {
103  this->SetDesc(_("Read a memo or memos"));
104  this->SetSyntax(_("[\037channel\037] {\037num\037 | \037list\037 | LAST | NEW}"));
105  }
106 
107  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
108  {
109 
110  MemoInfo *mi;
111  ChannelInfo *ci = NULL;
112  Anope::string numstr = params[0], chan;
113 
114  if (!numstr.empty() && numstr[0] == '#')
115  {
116  chan = numstr;
117  numstr = params.size() > 1 ? params[1] : "";
118 
119  ci = ChannelInfo::Find(chan);
120  if (!ci)
121  {
122  source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
123  return;
124  }
125  else if (!source.AccessFor(ci).HasPriv("MEMO"))
126  {
127  source.Reply(ACCESS_DENIED);
128  return;
129  }
130  mi = &ci->memos;
131  }
132  else
133  mi = &source.nc->memos;
134 
135  if (numstr.empty() || (!numstr.equals_ci("LAST") && !numstr.equals_ci("NEW") && !numstr.is_number_only()))
136  this->OnSyntaxError(source, numstr);
137  else if (mi->memos->empty())
138  {
139  if (!chan.empty())
140  source.Reply(MEMO_X_HAS_NO_MEMOS, chan.c_str());
141  else
142  source.Reply(MEMO_HAVE_NO_MEMOS);
143  }
144  else
145  {
146  int i, end;
147 
148  if (numstr.equals_ci("NEW"))
149  {
150  int readcount = 0;
151  for (i = 0, end = mi->memos->size(); i < end; ++i)
152  if (mi->GetMemo(i)->unread)
153  {
154  MemoListCallback::DoRead(source, mi, ci, i);
155  ++readcount;
156  }
157  if (!readcount)
158  {
159  if (!chan.empty())
160  source.Reply(MEMO_X_HAS_NO_NEW_MEMOS, chan.c_str());
161  else
162  source.Reply(MEMO_HAVE_NO_NEW_MEMOS);
163  }
164  }
165  else if (numstr.equals_ci("LAST"))
166  {
167  for (i = 0, end = mi->memos->size() - 1; i < end; ++i);
168  MemoListCallback::DoRead(source, mi, ci, i);
169  }
170  else /* number[s] */
171  {
172  MemoListCallback list(source, mi, ci, numstr);
173  list.Process();
174  }
175  }
176  return;
177  }
178 
179  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
180  {
181  this->SendSyntax(source);
182  source.Reply(" ");
183  source.Reply(_("Sends you the text of the memos specified. If LAST is\n"
184  "given, sends you the memo you most recently received. If\n"
185  "NEW is given, sends you all of your new memos. Otherwise,\n"
186  "sends you memo number \037num\037. You can also give a list of\n"
187  "numbers, as in this example:\n"
188  " \n"
189  " \002READ 2-5,7-9\002\n"
190  " Displays memos numbered 2 through 5 and 7 through 9."));
191  return true;
192  }
193 };
194 
195 class MSRead : public Module
196 {
198 
199  public:
200  MSRead(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
201  commandmsread(this)
202  {
203 
204  }
205 };
206 
Serialize::Reference< NickCore > nc
Definition: account.h:47
Definition: bots.h:24
CoreExport bool ReadOnly
Definition: main.cpp:28
virtual MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force=false)=0
static NickAlias * Find(const Anope::string &nick)
Definition: nickalias.cpp:121
Definition: hashcomp.h:84
CommandMSRead commandmsread
Definition: ms_read.cpp:197
MemoInfo * mi
Definition: ms_read.cpp:53
Anope::string name
Definition: regchannel.h:63
static ServiceReference< MemoServService > MemoServService("MemoServService","MemoServ")
Anope::string text
Definition: memo.h:34
#define ACCESS_DENIED
Definition: language.h:73
CoreExport string printf(const char *fmt,...)
Definition: misc.cpp:536
static bool FindCommandFromService(const Anope::string &command_service, BotInfo *&bi, Anope::string &name)
Definition: command.cpp:287
CommandMSRead(Module *creator)
Definition: ms_read.cpp:101
Anope::string sender
Definition: memo.h:33
CommandSource & source
Definition: ms_read.cpp:52
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
bool equals_ci(const char *_str) const
Definition: anope.h:78
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
Definition: ms_read.cpp:179
#define MEMO_HAVE_NO_MEMOS
Definition: language.h:115
const Anope::string & GetNick() const
Definition: command.cpp:26
static void rsend_notify(CommandSource &source, MemoInfo *mi, Memo *m, const Anope::string &targ)
Definition: ms_read.cpp:16
bool receipt
Definition: memo.h:23
static ChannelInfo * Find(const Anope::string &name)
Definition: regchannel.cpp:630
const ChannelInfo * ci
Definition: ms_read.cpp:54
#define MEMO_X_HAS_NO_MEMOS
Definition: language.h:116
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: ms_read.cpp:107
Definition: Config.cs:26
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
Definition: command.cpp:191
Definition: memo.h:40
void Reply(const char *message,...)
Definition: command.cpp:96
Definition: memo.h:19
Anope::string display
Definition: account.h:113
Memo * GetMemo(unsigned index) const
Definition: memos.cpp:82
MemoListCallback(CommandSource &_source, MemoInfo *_mi, const ChannelInfo *_ci, const Anope::string &numlist)
Definition: ms_read.cpp:56
MSRead(const Anope::string &modname, const Anope::string &creator)
Definition: ms_read.cpp:200
#define anope_override
Definition: services.h:56
bool empty() const
Definition: anope.h:126
#define MEMO_X_HAS_NO_NEW_MEMOS
Definition: language.h:119
MemoInfo memos
Definition: regchannel.h:77
#define MODULE_INIT(x)
Definition: modules.h:45
CoreExport const char * Translate(const char *string)
Definition: language.cpp:59
void SetSyntax(const Anope::string &s)
Definition: command.cpp:140
void Process()
Definition: misc.cpp:98
#define CHAN_X_NOT_REGISTERED
Definition: language.h:84
Anope::string nick
Definition: users.h:62
Serialize::Checker< std::vector< Memo * > > memos
Definition: memo.h:43
static void DoRead(CommandSource &source, MemoInfo *mi, const ChannelInfo *ci, unsigned index)
Definition: ms_read.cpp:68
void SendSyntax(CommandSource &)
Definition: command.cpp:145
NickCore * GetAccount()
Definition: command.cpp:36
const char * c_str() const
Definition: anope.h:117
time_t time
Definition: memo.h:32
void HandleNumber(unsigned number) anope_override
Definition: ms_read.cpp:60
CoreExport Anope::string strftime(time_t t, const NickCore *nc=NULL, bool short_output=false)
Definition: misc.cpp:356
bool is_number_only() const
Definition: anope.h:217
bool unread
Definition: memo.h:22
#define _(x)
Definition: services.h:50
#define MEMO_HAVE_NO_NEW_MEMOS
Definition: language.h:118