1 /*
2 * Copyright (C) 2004-2020 ZNC, see the NOTICE file for details.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <znc/znc.h>
18
19 using std::stringstream;
20
21 class CNotesMod : public CModule {
22 bool m_bShowNotesOnLogin{};
23
ListCommand(const CString & sLine)24 void ListCommand(const CString& sLine) { ListNotes(); }
25
AddNoteCommand(const CString & sLine)26 void AddNoteCommand(const CString& sLine) {
27 CString sKey(sLine.Token(1));
28 CString sValue(sLine.Token(2, true));
29
30 if (!GetNV(sKey).empty()) {
31 PutModule(
32 t_s("That note already exists. Use MOD <key> <note> to "
33 "overwrite."));
34 } else if (AddNote(sKey, sValue)) {
35 PutModule(t_f("Added note {1}")(sKey));
36 } else {
37 PutModule(t_f("Unable to add note {1}")(sKey));
38 }
39 }
40
ModCommand(const CString & sLine)41 void ModCommand(const CString& sLine) {
42 CString sKey(sLine.Token(1));
43 CString sValue(sLine.Token(2, true));
44
45 if (AddNote(sKey, sValue)) {
46 PutModule(t_f("Set note for {1}")(sKey));
47 } else {
48 PutModule(t_f("Unable to add note {1}")(sKey));
49 }
50 }
51
GetCommand(const CString & sLine)52 void GetCommand(const CString& sLine) {
53 CString sNote = GetNV(sLine.Token(1, true));
54
55 if (sNote.empty()) {
56 PutModule(t_s("This note doesn't exist."));
57 } else {
58 PutModule(sNote);
59 }
60 }
61
DelCommand(const CString & sLine)62 void DelCommand(const CString& sLine) {
63 CString sKey(sLine.Token(1));
64
65 if (DelNote(sKey)) {
66 PutModule(t_f("Deleted note {1}")(sKey));
67 } else {
68 PutModule(t_f("Unable to delete note {1}")(sKey));
69 }
70 }
71
72 public:
MODCONSTRUCTOR(CNotesMod)73 MODCONSTRUCTOR(CNotesMod) {
74 AddHelpCommand();
75 AddCommand("List", "", t_d("List notes"),
76 [=](const CString& sLine) { ListCommand(sLine); });
77 AddCommand("Add", t_d("<key> <note>"), t_d("Add a note"),
78 [=](const CString& sLine) { AddNoteCommand(sLine); });
79 AddCommand("Del", t_d("<key>"), t_d("Delete a note"),
80 [=](const CString& sLine) { DelCommand(sLine); });
81 AddCommand("Mod", t_d("<key> <note>"), t_d("Modify a note"),
82 [=](const CString& sLine) { ModCommand(sLine); });
83 AddCommand("Get", t_d("<key>"), "",
84 [=](const CString& sLine) { GetCommand(sLine); });
85 }
86
~CNotesMod()87 ~CNotesMod() override {}
88
OnLoad(const CString & sArgs,CString & sMessage)89 bool OnLoad(const CString& sArgs, CString& sMessage) override {
90 m_bShowNotesOnLogin = !sArgs.Equals("-disableNotesOnLogin");
91 return true;
92 }
93
GetWebMenuTitle()94 CString GetWebMenuTitle() override { return t_s("Notes"); }
95
OnClientLogin()96 void OnClientLogin() override {
97 if (m_bShowNotesOnLogin) {
98 ListNotes(true);
99 }
100 }
101
OnUserRaw(CString & sLine)102 EModRet OnUserRaw(CString& sLine) override {
103 if (sLine.Left(1) != "#") {
104 return CONTINUE;
105 }
106
107 CString sKey;
108 bool bOverwrite = false;
109
110 if (sLine == "#?") {
111 ListNotes(true);
112 return HALT;
113 } else if (sLine.Left(2) == "#-") {
114 sKey = sLine.Token(0).LeftChomp_n(2);
115 if (DelNote(sKey)) {
116 PutModNotice(t_f("Deleted note {1}")(sKey));
117 } else {
118 PutModNotice(t_f("Unable to delete note {1}")(sKey));
119 }
120 return HALT;
121 } else if (sLine.Left(2) == "#+") {
122 sKey = sLine.Token(0).LeftChomp_n(2);
123 bOverwrite = true;
124 } else if (sLine.Left(1) == "#") {
125 sKey = sLine.Token(0).LeftChomp_n(1);
126 }
127
128 CString sValue(sLine.Token(1, true));
129
130 if (!sKey.empty()) {
131 if (!bOverwrite && FindNV(sKey) != EndNV()) {
132 PutModNotice(
133 t_s("That note already exists. Use /#+<key> <note> to "
134 "overwrite."));
135 } else if (AddNote(sKey, sValue)) {
136 if (!bOverwrite) {
137 PutModNotice(t_f("Added note {1}")(sKey));
138 } else {
139 PutModNotice(t_f("Set note for {1}")(sKey));
140 }
141 } else {
142 PutModNotice(t_f("Unable to add note {1}")(sKey));
143 }
144 }
145
146 return HALT;
147 }
148
DelNote(const CString & sKey)149 bool DelNote(const CString& sKey) { return DelNV(sKey); }
150
AddNote(const CString & sKey,const CString & sNote)151 bool AddNote(const CString& sKey, const CString& sNote) {
152 if (sKey.empty()) {
153 return false;
154 }
155
156 return SetNV(sKey, sNote);
157 }
158
ListNotes(bool bNotice=false)159 void ListNotes(bool bNotice = false) {
160 CClient* pClient = GetClient();
161
162 if (pClient) {
163 CTable Table;
164 Table.AddColumn(t_s("Key"));
165 Table.AddColumn(t_s("Note"));
166 Table.SetStyle(CTable::ListStyle);
167
168 for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) {
169 Table.AddRow();
170 Table.SetCell(t_s("Key"), it->first);
171 Table.SetCell(t_s("Note"), it->second);
172 }
173
174 if (Table.size()) {
175 unsigned int idx = 0;
176 CString sLine;
177 while (Table.GetLine(idx++, sLine)) {
178 if (bNotice) {
179 pClient->PutModNotice(GetModName(), sLine);
180 } else {
181 pClient->PutModule(GetModName(), sLine);
182 }
183 }
184 } else {
185 if (bNotice) {
186 PutModNotice(t_s("You have no entries."));
187 } else {
188 PutModule(t_s("You have no entries."));
189 }
190 }
191 }
192 }
193
OnWebRequest(CWebSock & WebSock,const CString & sPageName,CTemplate & Tmpl)194 bool OnWebRequest(CWebSock& WebSock, const CString& sPageName,
195 CTemplate& Tmpl) override {
196 if (sPageName == "index") {
197 for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) {
198 CTemplate& Row = Tmpl.AddRow("NotesLoop");
199
200 Row["Key"] = it->first;
201 Row["Note"] = it->second;
202 }
203
204 return true;
205 } else if (sPageName == "delnote") {
206 DelNote(WebSock.GetParam("key", false));
207 WebSock.Redirect(GetWebPath());
208 return true;
209 } else if (sPageName == "addnote") {
210 AddNote(WebSock.GetParam("key"), WebSock.GetParam("note"));
211 WebSock.Redirect(GetWebPath());
212 return true;
213 }
214
215 return false;
216 }
217 };
218
219 template <>
TModInfo(CModInfo & Info)220 void TModInfo<CNotesMod>(CModInfo& Info) {
221 Info.SetWikiPage("notes");
222 Info.SetHasArgs(true);
223 Info.SetArgsHelpText(
224 Info.t_s("This user module takes up to one arguments. It can be "
225 "-disableNotesOnLogin not to show notes upon client login"));
226 }
227
228 USERMODULEDEFS(CNotesMod, t_s("Keep and replay notes"))
229