diff --git a/README.md b/README.md index 0a80b0a..187e16c 100644 --- a/README.md +++ b/README.md @@ -66,5 +66,5 @@ After all of that you're good to go! Happy using :) * [ ] Get application by id and user_id * [x] Age as a DD.MM.YYYY * [ ] Notify about upcoming birthdays -* [ ] Change the application data +* [x] Change the application data * [x] Check if user is already in group \ No newline at end of file diff --git a/config_example.json b/config_example.json index 6f76c2e..8d4fa1d 100644 --- a/config_example.json +++ b/config_example.json @@ -19,7 +19,7 @@ "locale": "locale" }, "commands": { - "start": "Start using the bot" + "reapply": "Fill the application again" }, "commands_admin": { "reboot": "Restart the bot", diff --git a/data/user_default.json b/data/user_default.json index 45567bd..d4e522c 100644 --- a/data/user_default.json +++ b/data/user_default.json @@ -1,5 +1,6 @@ { "stage": 0, + "reapply": false, "link": null, "sent": false, "confirmed": false, diff --git a/locale/uk.json b/locale/uk.json index 561f6b3..3db8e0a 100644 --- a/locale/uk.json +++ b/locale/uk.json @@ -27,17 +27,16 @@ "confirm": "Супер, дякуємо!\n\nБудь ласка, перевір правильність даних:\n{0}\n\nВсе правильно?", "application_sent": "Дякуємо! Ми надіслали твою анкетку на перевірку. Ти отримаєш повідомлення як тільки її перевірять та приймуть рішення. До тих пір від тебе більше нічого не потребується. Гарного дня! :)", "application_got": "Отримано анкету від `{0}`\n\nІм'я тг: `{1}`, `{2}`\nUserID: `{3}`\n\n**Дані анкети:**\n{4}", + "reapply_got": "Отримано змінити анкети від `{0}`\n\nІм'я тг: `{1}`, `{2}`\nUserID: `{3}`\n\n**Дані анкети:**\n{4}", "shutdown": "Вимкнення бота з підом `{0}`", "startup": "Запуск бота з підом `{0}`", "startup_downtime": "Запуск бота з підом `{0}` (лежав {1})", - "sub_yes": "✅ Подання схвалено та прийнято", - "sub_no": "❌ Подання розглянуто та відхилено", "approved": "Вітаємо! Твою анкету переглянули та підтвердили твоє право на вступ. Скористайся кнопкою під повідомленням щоб вступити до нашої лампової спільноти!", "approved_joined": "Вітаємо! Твою анкету переглянули та підтвердили її правильність. Дякуємо за витрачений на заповнення час та гарного дня!", "refused": "Ой лишенько! Твою анкету переглянули, однак не підтвердили право на вступ до спільноти. Better luck next time!", "refused_russian": "русский военньій корабль, иди нахуй!", - "approved_by": "✅ **Анкету схвалено**\nАдмін **{0}** переглянув та схвалив анкету `{1}`, дозволивши вступ до спільноти.", - "refused_by": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`, заборонивши вступ до спільноти.", + "approved_by": "✅ **Анкету схвалено**\nАдмін **{0}** переглянув та схвалив анкету `{1}`.", + "refused_by": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`.", "refused_by_agr": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`, заборонивши вступ до спільноти.\nПричина: агресивна/токсична анкета.", "refused_by_rus": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`, заборонивши вступ до спільноти.\nПричина: русня.", "contact": "Анкета `{0}`\n\n**Дані анкети:**\n{1}\n\n{2}", @@ -51,6 +50,8 @@ "sus_joined": "Користувач **{0}** (`{1}`) зайшов до групи не за своїм персональним запрошенням.", "sus_allowed_by": "✅ **Доступ дозволено**\nАдмін **{0}** дозволив `{1}` вступити до спільноти не за персональним посиланням.", "sus_refused_by": "❌ **Доступ заборонено**\nАдмін **{0}** заборонив `{1}` доступ до спільноти не за персональним посиланням.", + "reapply_forbidden": "❌ **Дія неможлива**\nТвоя минула анкета ще не була схвалена або відхилена.", + "reapply_in_progress": "❌ **Дія неможлива**\nТи прямо зараз вже заповнюєш анкету. Якщо в ній є помилка - після заповнення просто натисни **{0}** та почни знову.", "question_titles": { "question1": "Ім'я/звертання:", "question2": "День народження:", @@ -110,7 +111,9 @@ "sus_allow": "✅ Підтвердити дозвіл", "sus_refuse": "❌ Перманентно заблокувати", "sus_allowed": "✅ Дозвіл надано", - "sus_refused": "❌ Користувача заблоковано" + "sus_refused": "❌ Користувача заблоковано", + "reapply_yes": "✅ Прийняти", + "reapply_no": "❌ Відхилити" }, "callback": { "sub_accepted": "✅ Анкету {0} схвалено", diff --git a/main.py b/main.py index 200df3d..fcff820 100644 --- a/main.py +++ b/main.py @@ -68,6 +68,25 @@ async def cmd_applications(app, msg): # ============================================================================================================================== +# Reapply command ============================================================================================================== +@app.on_message(~ filters.scheduled & filters.private & filters.command(["reapply"], prefixes=["", "/"])) +async def cmd_reapply(app, msg): + + if configGet("approved", file=str(msg.from_user.id)) or configGet("refused", file=str(msg.from_user.id)): + if (configGet("stage", file=str(msg.from_user.id)) == 10) and not (configGet("sent", file=str(msg.from_user.id))): + configSet("reapply", True, file=str(msg.from_user.id)) + configSet("confirmed", False, file=str(msg.from_user.id)) + await welcome_pass(app, msg, once_again=True) + else: + await msg.reply_text(locale("reapply_in_progress", "message").format(locale("confirm", "keyboard")[1][0])) + else: + if configGet("sent", file=str(msg.from_user.id)): + await msg.reply_text(locale("reapply_forbidden", "message")) + else: + await msg.reply_text(locale("reapply_in_progress", "message").format(locale("confirm", "keyboard")[1][0])) +# ============================================================================================================================== + + # Welcome check ================================================================================================================ @app.on_message(~ filters.scheduled & filters.private & (filters.regex(locale("welcome", "keyboard")[0][0]) | filters.regex(locale("return", "keyboard")[0][0]))) async def welcome_pass(app, msg, once_again: bool = True): @@ -78,6 +97,7 @@ async def welcome_pass(app, msg, once_again: bool = True): logWrite(f"User {msg.from_user.id} confirmed starting the application") await msg.reply_text(locale("question1", "message"), reply_markup=ForceReply(placeholder=locale("question1", "force_reply"))) # type: ignore configSet("stage", 1, file=str(msg.from_user.id)) + configSet("sent", False, file=str(msg.from_user.id)) @app.on_message(~ filters.scheduled & filters.private & (filters.regex(locale("welcome", "keyboard")[1][0]))) async def welcome_reject(app, msg): @@ -125,23 +145,36 @@ async def confirm_yes(app, msg): application_content.append(f"{locale('question'+str(i), 'message', 'question_titles')} {configGet('application', file=str(msg.from_user.id))[question]}") i += 1 - await app.send_message(chat_id=configGet("admin_group"), text=(locale("application_got", "message")).format(str(msg.from_user.id), msg.from_user.first_name, msg.from_user.last_name, msg.from_user.username, "\n".join(application_content)), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( # type: ignore - [ + if configGet("reapply", file=str(msg.from_user.id)): + await app.send_message(chat_id=configGet("admin_group"), text=(locale("reapply_got", "message")).format(str(msg.from_user.id), msg.from_user.first_name, msg.from_user.last_name, msg.from_user.username, "\n".join(application_content)), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( # type: ignore [ - InlineKeyboardButton(text=str(locale("sub_yes", "button")), callback_data=f"sub_yes_{msg.from_user.id}") - ], - [ - InlineKeyboardButton(text=str(locale("sub_no", "button")), callback_data=f"sub_no_{msg.from_user.id}") - ], - [ - InlineKeyboardButton(text=str(locale("sub_no_aggressive", "button")), callback_data=f"sub_no_aggresive_{msg.from_user.id}") - ], - [ - InlineKeyboardButton(text=str(locale("sub_no_russian", "button")), callback_data=f"sub_no_russian_{msg.from_user.id}") + [ + InlineKeyboardButton(text=str(locale("reapply_yes", "button")), callback_data=f"reapply_yes_{msg.from_user.id}") + ], + [ + InlineKeyboardButton(text=str(locale("reapply_no", "button")), callback_data=f"reapply_no_{msg.from_user.id}") + ] ] - ] + ) + ) + else: + await app.send_message(chat_id=configGet("admin_group"), text=(locale("application_got", "message")).format(str(msg.from_user.id), msg.from_user.first_name, msg.from_user.last_name, msg.from_user.username, "\n".join(application_content)), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( # type: ignore + [ + [ + InlineKeyboardButton(text=str(locale("sub_yes", "button")), callback_data=f"sub_yes_{msg.from_user.id}") + ], + [ + InlineKeyboardButton(text=str(locale("sub_no", "button")), callback_data=f"sub_no_{msg.from_user.id}") + ], + [ + InlineKeyboardButton(text=str(locale("sub_no_aggressive", "button")), callback_data=f"sub_no_aggresive_{msg.from_user.id}") + ], + [ + InlineKeyboardButton(text=str(locale("sub_no_russian", "button")), callback_data=f"sub_no_russian_{msg.from_user.id}") + ] + ] + ) ) - ) logWrite(f"User {msg.from_user.id} sent his application and it will now be reviewed") @@ -194,6 +227,7 @@ async def callback_query_accept(app, clb): await app.send_message(int(fullclb[2]), locale("approved_joined", "message")) configSet("approved", True, file=fullclb[2]) + configSet("sent", False, file=fullclb[2]) application = jsonLoad(f"{configGet('data', 'locations')}{sep}applications.json") application[fullclb[2]]["approved"] = True @@ -216,6 +250,7 @@ async def callback_query_refuse_aggressive(app, clb): logWrite(f"User {fullclb[3]} got refused by {clb.from_user.id} due to being aggressive") configSet("refused", True, file=fullclb[3]) + configSet("sent", False, file=fullclb[3]) application = jsonLoad(f"{configGet('data', 'locations')}{sep}applications.json") application[fullclb[3]]["refused"] = True @@ -239,6 +274,7 @@ async def callback_query_refuse_russian(app, clb): logWrite(f"User {fullclb[3]} got refused by {clb.from_user.id} due to being russian") configSet("refused", True, file=fullclb[3]) + configSet("sent", False, file=fullclb[3]) application = jsonLoad(f"{configGet('data', 'locations')}{sep}applications.json") application[fullclb[3]]["refused"] = True @@ -261,6 +297,58 @@ async def callback_query_refuse(app, clb): logWrite(f"User {fullclb[2]} got refused by {clb.from_user.id}") configSet("refused", True, file=fullclb[2]) + configSet("sent", False, file=fullclb[2]) + + application = jsonLoad(f"{configGet('data', 'locations')}{sep}applications.json") + application[fullclb[2]]["refused"] = True + application[fullclb[2]]["refused_by"] = clb.from_user.id + application[fullclb[2]]["refusal_date"] = int(time()) + jsonSave(application, f"{configGet('data', 'locations')}{sep}applications.json") + + edited_markup = [[InlineKeyboardButton(text=str(locale("declined", "button")), callback_data="nothing")]] + + await clb.message.edit(text=clb.message.text, reply_markup=InlineKeyboardMarkup(edited_markup)) + await clb.answer(text=locale("sub_refused", "callback").format(fullclb[2]), show_alert=True) # type: ignore +# ============================================================================================================================== + + + +# Callbacks application ======================================================================================================== +@app.on_callback_query(filters.regex("reapply_yes_[\s\S]*")) # type: ignore +async def callback_query_accept(app, clb): + + fullclb = clb.data.split("_") + + await app.send_message(configGet("admin_group"), locale("approved_by", "message").format(clb.from_user.first_name, fullclb[2]), disable_notification=True) # type: ignore + logWrite(f"User {fullclb[2]} got their reapplication approved by {clb.from_user.id}") + + await app.send_message(int(fullclb[2]), locale("approved_joined", "message")) + + configSet("approved", True, file=fullclb[2]) + configSet("sent", False, file=fullclb[2]) + + application = jsonLoad(f"{configGet('data', 'locations')}{sep}applications.json") + application[fullclb[2]]["approved"] = True + application[fullclb[2]]["approved_by"] = clb.from_user.id + application[fullclb[2]]["approval_date"] = int(time()) + jsonSave(application, f"{configGet('data', 'locations')}{sep}applications.json") + + edited_markup = [[InlineKeyboardButton(text=str(locale("accepted", "button")), callback_data="nothing")]] + + await clb.message.edit(text=clb.message.text, reply_markup=InlineKeyboardMarkup(edited_markup)) + await clb.answer(text=locale("sub_accepted", "callback").format(fullclb[2]), show_alert=True) # type: ignore + +@app.on_callback_query(filters.regex("reapply_no_[\s\S]*")) # type: ignore +async def callback_query_refuse(app, clb): + + fullclb = clb.data.split("_") + + await app.send_message(configGet("admin_group"), locale("refused_by", "message").format(clb.from_user.first_name, fullclb[2]), disable_notification=True) # type: ignore + await app.send_message(int(fullclb[2]), locale("refused", "message")) + logWrite(f"User {fullclb[2]} got their reapplication refused by {clb.from_user.id}") + + configSet("refused", True, file=fullclb[2]) + configSet("sent", False, file=fullclb[2]) application = jsonLoad(f"{configGet('data', 'locations')}{sep}applications.json") application[fullclb[2]]["refused"] = True @@ -342,8 +430,8 @@ async def get_contact(app, msg): else: application_content.append(f"{locale('question'+str(i), 'message', 'question_titles')} {configGet('application', file=str(msg.contact.user_id))[question]}") i += 1 + application = jsonLoad(f"{configGet('data', 'locations')}{sep}applications.json")[str(msg.contact.user_id)] if user_data["sent"]: - application = jsonLoad(f"{configGet('data', 'locations')}{sep}applications.json")[str(msg.contact.user_id)] if user_data["approved"]: application_status = locale("application_status_accepted", "message").format((await app.get_users(application["approved_by"])).first_name, datetime.fromtimestamp(application["approval_date"]).strftime("%d.%m.%Y, %H:%M")) # type: ignore elif application["refused"]: @@ -351,7 +439,12 @@ async def get_contact(app, msg): else: application_status = locale("application_status_on_hold", "message") else: - application_status = locale("application_status_not_send", "message") + if user_data["approved"]: + application_status = locale("application_status_accepted", "message").format((await app.get_users(application["approved_by"])).first_name, datetime.fromtimestamp(application["approval_date"]).strftime("%d.%m.%Y, %H:%M")) # type: ignore + elif application["refused"]: + application_status = locale("application_status_refused", "message").format((await app.get_users(application["refused_by"])).first_name, datetime.fromtimestamp(application["refusal_date"]).strftime("%d.%m.%Y, %H:%M")) # type: ignore + else: + application_status = locale("application_status_not_send", "message") logWrite(f"User {msg.from_user.id} requested application of {msg.contact.user_id}") await msg.reply_text(locale("contact", "message").format(str(msg.contact.user_id), "\n".join(application_content), application_status)) # type: ignore except FileNotFoundError: @@ -419,7 +512,8 @@ async def any_stage(app, msg): #configSet("sent", True, file=str(msg.from_user.id)) #configSet("application_date", int(time()), file=str(msg.from_user.id)) else: - await msg.reply_text(locale("already_sent", "message")) + if not configGet("approved", file=str(msg.from_user.id)) and not configGet("refused", file=str(msg.from_user.id)): + await msg.reply_text(locale("already_sent", "message")) else: if not configGet("approved", file=str(msg.from_user.id)) and not configGet("refused", file=str(msg.from_user.id)): await msg.reply_text(locale("already_sent", "message")) @@ -466,16 +560,16 @@ if __name__ == "__main__": app.send_message(configGet("owner"), f"Starting up with pid `{pid}`") # type: ignore - # # Registering user commands - # commands_list = [] - # for command in configGet("commands"): - # commands_list.append(BotCommand(command, configGet("commands")[command])) - # app.set_bot_commands(commands_list) # type: ignore + # Registering user commands + commands_list = [] + for command in configGet("commands"): + commands_list.append(BotCommand(command, configGet("commands")[command])) + app.set_bot_commands(commands_list) # type: ignore # Registering admin commands commands_admin_list = [] - # for command in configGet("commands"): - # commands_admin_list.append(BotCommand(command, configGet("commands")[command])) + for command in configGet("commands"): + commands_admin_list.append(BotCommand(command, configGet("commands")[command])) for command in configGet("commands_admin"): commands_admin_list.append(BotCommand(command, configGet("commands_admin")[command]))