Skip to content

Commit 83583a1

Browse files
committed
Implement the RemoveAdminHandler.
For avoiding the code duplicate we also add the ModifyAdminsHandler class in which we move the all forward/username detection logic. Now the handlers hierarchy looks like that: +-+-PostHandler +-+->ModifyPostHandler +->AddAdminHandler +->RemoveAdminHandler +->PhotoChannelAddPostHandler
1 parent 2c71fcf commit 83583a1

File tree

1 file changed

+182
-35
lines changed

1 file changed

+182
-35
lines changed

main.cpp

Lines changed: 182 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -213,24 +213,12 @@ class PhotoChannelPostHandler : public PostHandler {
213213
}
214214
};
215215

216-
const char *fileadminslist = "adminsnames";
217-
const char *fileadminidslist = "adminsids"; // if the admin has not a @username.
218-
219-
class AddAdminHandler : public PostHandler {
216+
class ModifyAdminsHandler : public PostHandler {
217+
protected:
220218
TgUsersList &h; // the separate list for admin's ids.
221219
TgUserNamesList &adminNamesList;
222220
const std::string chanName;
223221

224-
void addUserToAdminsFromForward(CURL *c, TgInteger chatId, const json &msg)
225-
{
226-
auto &fwd = msg["forward_from"];
227-
TgInteger id = fwd["id"].get<TgInteger>();
228-
easy_perform_sendMessage(c, chatId,
229-
"Готово. Пользователь добавлен в список редакторов канала.", TgMessageParse_Normal, 0);
230-
// easy_perform_sendMessage(c, chatId, (std::string("Ок. пользователь добавлен в список администраторов канала.") + std::to_string(id)).c_str(), 0);
231-
h.addId(id);
232-
}
233-
234222
bool messageIsForward(const json &msg) const
235223
{
236224
return msg.find("forward_from") != msg.end()
@@ -243,16 +231,53 @@ class AddAdminHandler : public PostHandler {
243231
size_t len = msg.length();
244232
return len != 0 && msg[0] == '@';
245233
}
234+
235+
virtual bool handleForward(CURL *c, TgInteger chatId, It currentUserId, const json &msg, bool fromCancel) = 0;
236+
virtual bool handleMessage(CURL *c, TgInteger chatId, It currentUserId, const json &msg) = 0;
237+
238+
public:
239+
class ModifyEntriesListener {
240+
public:
241+
enum NotifyType {
242+
ModifyAdminName,
243+
ModifyAdminId
244+
};
245+
246+
virtual void notify(NotifyType type) = 0;
247+
virtual ~ModifyEntriesListener() {}
248+
};
249+
protected:
250+
void notifyListener(ModifyEntriesListener::NotifyType type)
251+
{
252+
if (listener) {
253+
listener->notify(type);
254+
}
255+
}
256+
private:
257+
class ModifyEntriesListener *listener;
246258
public:
247-
AddAdminHandler(const char *name,
259+
void addListener(ModifyEntriesListener &l)
260+
{
261+
listener = &l;
262+
}
263+
264+
void removeListener()
265+
{
266+
listener = nullptr;
267+
}
268+
269+
ModifyAdminsHandler(const char *name,
248270
TgUsersList &hn, TgUserNamesList &l)
249271
: h(hn), chanName(name), adminNamesList(l) {}
250272

251273
bool onCancel(CURL *c, TgInteger chatId, It it, const json &msg) override
252274
{
253275
if (messageIsForward(msg)) {
254-
addUserToAdminsFromForward(c, chatId, msg);
255-
return true;
276+
if (handleForward(c, chatId, it, msg, true)) {
277+
stop(it);
278+
return true;
279+
}
280+
return false;
256281
}
257282
easy_perform_sendMessage(c, chatId, "Ок, команда отменена.", TgMessageParse_Normal, 0);
258283
return true;
@@ -267,34 +292,129 @@ class AddAdminHandler : public PostHandler {
267292
return true;
268293
}
269294

270-
TgInteger id = 0;
271-
bool is_fwd = messageIsForward(upd);
272-
if (is_fwd) {
273-
addUserToAdminsFromForward(c, chatId, upd);
274-
stop(it);
275-
return true;
295+
if (messageIsForward(upd)) {
296+
if (handleForward(c, chatId, it, upd, false)) {
297+
stop(it);
298+
return true;
299+
}
300+
return false;
276301
} else {
302+
if (handleMessage(c, chatId, it, upd)) {
303+
stop(it);
304+
return true;
305+
}
306+
return false;
307+
}
277308

278-
// todo, bleat.
279-
stop(it);
280-
// easy_perform_sendMessage(c, chatId, "вжух", TgMessageParse_Normal, 0);
309+
return true;
310+
}
311+
312+
};
313+
314+
class AddAdminHandler : public ModifyAdminsHandler {
315+
316+
void addUserToAdminsFromForward(CURL *c, TgInteger chatId, const json &msg)
317+
{
318+
auto &fwd = msg["forward_from"];
319+
TgInteger id = fwd["id"].get<TgInteger>();
320+
easy_perform_sendMessage(c, chatId,
321+
"Готово. Пользователь добавлен.", TgMessageParse_Normal, 0);
322+
h.addId(id);
323+
notifyListener(ModifyEntriesListener::ModifyAdminId);
324+
}
325+
326+
virtual bool handleForward(CURL *c, TgInteger chatId, It currentUserId, const json &msg, bool fromCancel) override
327+
{
328+
addUserToAdminsFromForward(c, chatId, msg);
329+
return true;
330+
}
331+
332+
bool handleMessage(CURL *c, TgInteger chatId, It currentUserId, const json &msg) override
333+
{
334+
std::string text = msg["text"].get<std::string>();
335+
if (messageIsAUsername(text)) {
336+
this->adminNamesList.push_back(text.substr(1));
337+
easy_perform_sendMessage(c, chatId, "Готово. Пользователь добавлен.", TgMessageParse_Normal, 0);
338+
notifyListener(ModifyEntriesListener::ModifyAdminName);
339+
return true;
281340
}
341+
return false;
342+
}
343+
public:
344+
AddAdminHandler(const char *channelName, TgUsersList &ids,
345+
TgUserNamesList &names)
346+
: ModifyAdminsHandler(channelName, ids, names) {}
347+
348+
bool onAddHandler(CURL *c, TgInteger fromId,
349+
TgInteger chatId) override
350+
{
351+
easy_perform_sendMessage(c, chatId, "Ок, отправь мне юзернейм (в виде @username), или форвард от пользователя, которого ты хочешь сделать редактором канала, или нажми /cancel для отмены.", TgMessageParse_Normal, 0);
282352
return true;
283353
}
284354

355+
};
356+
357+
class RemoveAdminHandler : public ModifyAdminsHandler {
358+
359+
bool removeUserFromAdminListFromForward(CURL *c, TgInteger chatId, const json &msg)
360+
{
361+
auto &fwd = msg["forward_from"];
362+
TgInteger id = fwd["id"].get<TgInteger>();
363+
auto res = h.findId(id);
364+
if (h.haveResultId(res)) {
365+
easy_perform_sendMessage(c, chatId,
366+
"Готово. Пользователь удален.", TgMessageParse_Normal, 0);
367+
h.removeResultId(res);
368+
notifyListener(ModifyEntriesListener::ModifyAdminId);
369+
return true;
370+
} else {
371+
easy_perform_sendMessage(c, chatId, "Такой пользователь не найден. Команда отменена.", TgMessageParse_Normal, 0);
372+
return false;
373+
}
374+
}
375+
protected:
376+
377+
virtual bool handleForward(CURL *c, TgInteger chatId, It currentUserId, const json &msg, bool fromCancel) override
378+
{
379+
removeUserFromAdminListFromForward(c, chatId, msg);
380+
return true;
381+
}
382+
383+
bool handleMessage(CURL *c, TgInteger chatId, It currentUserId, const json &msg) override
384+
{
385+
std::string text = msg["text"].get<std::string>();
386+
if (messageIsAUsername(text)) {
387+
auto res = std::find(this->adminNamesList.begin(),
388+
this->adminNamesList.end(), text.substr(1));
389+
if (res != this->adminNamesList.end()) {
390+
this->adminNamesList.erase(res);
391+
easy_perform_sendMessage(c, chatId, "Готово. Пользователь удален.", TgMessageParse_Normal, 0);
392+
notifyListener(ModifyEntriesListener::ModifyAdminName);
393+
} else {
394+
easy_perform_sendMessage(c, chatId, "Такой пользователь не найден. Команда отменена.", TgMessageParse_Normal, 0);
395+
}
396+
397+
return true;
398+
}
399+
return false;
400+
}
401+
402+
public:
403+
RemoveAdminHandler(const char *name, TgUsersList &ids, TgUserNamesList &names)
404+
: ModifyAdminsHandler(name, ids, names) {}
405+
285406
bool onAddHandler(CURL *c, TgInteger fromId,
286407
TgInteger chatId) override
287408
{
288-
easy_perform_sendMessage(c, chatId, "Ок, отправь мне форвард от того пользователя, которого ты хочешь сделать редактором канала.", TgMessageParse_Normal, 0);
409+
easy_perform_sendMessage(c, chatId, "Ок, отправь мне юзернейм (в виде @username), или форвард от пользователя, которого ты хочешь удалить из редакторов канала, или нажми /cancel для отмены.", TgMessageParse_Normal, 0);
289410
return true;
290411
}
412+
291413
};
292414

293415
class BotCommandsHandler {
294416
std::map<std::string, std::unique_ptr<BotCommand> > commands;
295-
296417
public:
297-
298418
bool handleCommands(CURL *c, TgInteger fromId,
299419
TgInteger chatId, const json &upd)
300420
{
@@ -340,21 +460,45 @@ class ResponseBotCommand : public BotCommand {
340460

341461
class PostCommandHandler : public BotCommand {
342462
PhotoChannelPostHandler &h;
463+
TgUsersList &ids;
464+
TgUserNamesList &names;
343465
public:
344-
PostCommandHandler(PhotoChannelPostHandler &ph) : h(ph) {}
466+
PostCommandHandler(PhotoChannelPostHandler &ph,
467+
TgUsersList &ids, TgUserNamesList &names)
468+
: h(ph), ids(ids), names(names) {}
345469

346470
virtual bool command(CURL *c, const json &upd, const std::string &cmd, size_t off, TgInteger fromId, TgInteger chatId) override
347471
{
472+
if (!ids.haveId(fromId)) {
473+
// check username.
474+
const auto &usr = upd.find("from");
475+
if (usr == upd.end() && !upd.is_object()) {
476+
return false;
477+
}
478+
const auto &name = upd.find("username");
479+
if (name == upd.cend()) {
480+
return false;
481+
}
482+
auto s = name->get<std::string>();
483+
if (s.empty()) {
484+
return false;
485+
}
486+
s = s.substr(1);
487+
if (std::find(names.begin(), names.end(), s) == names.end()) {
488+
return false;
489+
}
490+
}
491+
348492
h.addPostCommand(c, fromId, chatId);
349493

350494
return true;
351495
}
352496
};
353497

354-
class AddAdminCommand : public BotCommand {
355-
AddAdminHandler &h;
498+
class AdminCommand : public BotCommand {
499+
PostHandler &h;
356500
public:
357-
AddAdminCommand(AddAdminHandler &hn) : h(hn) {}
501+
AdminCommand(PostHandler &hn) : h(hn) {}
358502

359503
virtual bool command(CURL *c, const json &upd, const std::string &cmd, size_t off, TgInteger fromId, TgInteger chatId) override
360504
{
@@ -483,6 +627,7 @@ std::vector<std::string> adminNamesList;
483627
PhotoChannelPostHandler photoPostHandler(idPostChannel, postChannelName);
484628
BotCommandsHandler commandsHandler;
485629
AddAdminHandler addAdminsHandler(postChannelName, adminIdsList, adminNamesList);
630+
RemoveAdminHandler removeAdminsHandler(postChannelName, adminIdsList, adminNamesList);
486631
ListFlusher flusher(adminIdsList, adminNamesList, 10);
487632

488633
void handle_update_message(CURL *c, json &res, bool &quit, size_t &updateOffset)
@@ -539,16 +684,18 @@ int main(int argc, char *argv[])
539684

540685
// Create bot commands.
541686
commandsHandler.addCommand(postCommandName,
542-
std::make_unique<PostCommandHandler>(photoPostHandler));
687+
std::make_unique<PostCommandHandler>(photoPostHandler, adminIdsList, adminNamesList));
543688
commandsHandler.addCommand("start",
544689
std::make_unique<ResponseBotCommand>(
545690
std::string("Привет! Я @" BOT_NAME "! Я могу постить твои фотографии с подписями в канал. Чтобы это сделать, используй команду /") + postCommandName, TgMessageParse_Normal));
546691

547692
// Admin commands.
548693
commandsHandler.addCommand("addadmin",
549-
std::make_unique<AddAdminCommand>(addAdminsHandler));
694+
std::make_unique<AdminCommand>(addAdminsHandler));
550695
commandsHandler.addCommand("adminlist",
551696
std::make_unique<PrintUserListCommand>(adminIdsList, adminNamesList));
697+
commandsHandler.addCommand("removeadmin",
698+
std::make_unique<AdminCommand>(removeAdminsHandler));
552699

553700
// Add file flush listener
554701
addAdminsHandler.addListener(flusher);

0 commit comments

Comments
 (0)