diff --git a/README.md b/README.md index 0dc03e9..067b28d 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,10 @@

Files:


@@ -38,6 +40,9 @@

@@ -66,6 +74,12 @@
  • /bl {group_id} — show banned users
  • +
  • + /ban {user_id} — add user to blacklist +
  • +
  • + /show_groups — show groups id and name where bot are using +
  • /ub {user_id} — unban user
  • diff --git a/main.py b/main.py index 7b3a984..3872347 100644 --- a/main.py +++ b/main.py @@ -1,41 +1,55 @@ #!/usr/bin/env python3 # -*- encoding: utf-8 -*- -import config -import json -import random +__version__ = '1.3' + import sqlite3 -import os -import time from aiogram import Bot, Dispatcher, executor, types +from config import * +from random import randint +from json import loads +from os import path +from time import time -if not config.TOKEN: +if not TOKEN: print("[!] Empty token!!") exit() # initialization -bot = Bot(config.TOKEN) +bot = Bot(TOKEN) dp = Dispatcher(bot) print("[+] Bot initialization was successfully!") # if you want to read from json-file -content = json.loads(open("messages.json", "r", encoding="utf8").read()) +content = loads(open("messages.json", "r", encoding="utf8").read()) + + +class ass_info_obj(): + def __init__(self, ass_info: tuple): + self.id = ass_info[0] + self.username = ass_info[1] + self.name = ass_info[2] + self.length = ass_info[3] + self.endtime = ass_info[4] + self.spamcount = ass_info[5] + self.blacklisted = ass_info[6] def ass_main(ass_info, database, group_id): - ass_info = { - "id": ass_info[0], - "username": ass_info[1], - "name": ass_info[2], - "length": ass_info[3], - "endtime": ass_info[4], - "spamcount": ass_info[5], - "blacklisted": ass_info[6] - } - - if ass_info["endtime"] > int(time.time()): - last_time = ass_info["endtime"] - int(time.time()) + ''' + This function is backend part of function `ass` + + :param ass_info: Information about user from a database + :param database: Yeah, it's a database + :param group_id: Yeah, that's a group id + :return: Send to a database an query which change data. + ''' + + ass_info = ass_info_obj(ass_info) + + if ass_info.endtime > int(time()): + last_time = ass_info.endtime - int(time()) hours = int(last_time / 3600) last_time -= hours * 3600 @@ -43,48 +57,48 @@ def ass_main(ass_info, database, group_id): minutes = int(last_time / 60) last_time -= minutes * 60 - if ass_info["username"] == ass_info["name"]: - ass_info["username"] = ass_info["name"] + if ass_info.username == ass_info.name: + ass_info.username = ass_info.name else: try: - ass_info["username"] = "@" + ass_info["username"] + ass_info.username = "@" + ass_info.username except TypeError: - ass_info["username"] = "Анонимус" + ass_info.username = "Анонимус" if hours == 0: if minutes == 0: output_message = ( - "{0}, отуйсь заглянути залишилося меньше хвилини".format(ass_info["username"], minutes) + "{0}, готуйсь заглянути залишилося менше хвилини".format(ass_info.username, minutes) ) else: output_message = ( - "{0}, ти вже грав! Зачекай {1} хв.".format(ass_info["username"], minutes) + "{0}, ти вже грав! Зачекай {1} хв.".format(ass_info.username, minutes) ) else: if minutes == 0: output_message = ( - "{0}, ти вже грав! Зачекай {1} год.".format(ass_info["username"], hours) + "{0}, ти вже грав! Зачекай {1} год.".format(ass_info.username, hours) ) else: output_message = ( - "{0}, ти вже грав! Зачекай {1} год. {2} хв.".format(ass_info["username"], hours, minutes) + "{0}, ти вже грав! Зачекай {1} год. {2} хв.".format(ass_info.username, hours, minutes) ) database.execute(""" UPDATE `{0}` SET spamcount={1} WHERE user_id={2} - """.format(group_id, ass_info["spamcount"] + 1, ass_info["id"])) + """.format(group_id, ass_info.spamcount + 1, ass_info.id)) else: - tmp_length = random.randint(-8, 15) + tmp_length = randint(-8, 15) - if ass_info["username"] == ass_info["name"]: - ass_info["username"] = ass_info["name"] + if ass_info.username == ass_info.name: + ass_info.username = ass_info.name else: try: - ass_info["username"] = "@" + ass_info["username"] + ass_info.username = "@" + ass_info.username except TypeError: - ass_info["username"] = "Анонимус" + ass_info.username = "Анонимус" - output_message = "{0}, твоя дупця ".format(ass_info["username"]) + output_message = "{0}, твоя дупця ".format(ass_info.username) if tmp_length == 0: output_message += "не змінила розміру. " @@ -93,22 +107,22 @@ def ass_main(ass_info, database, group_id): "підросла на {0} см! Зараз твоя дупця прям бомбезна. ".format(tmp_length) ) elif tmp_length < 0: - if not ass_info["length"] - tmp_length <= 0: + if not ass_info.length - tmp_length <= 0: output_message += ( "зменшилась на {0} см! Зараз твоя дупця вже не файна. ".format(tmp_length * -1) ) - ass_info["length"] = ass_info["length"] + tmp_length + ass_info.length = ass_info.length + tmp_length - if ass_info["length"] < 0: - ass_info["length"] = 0 + if ass_info.length < 0: + ass_info.length = 0 output_message += "Зараз ти не маєш заду. " else: - output_message += "\nНаразі ваша дупенція становить: {0} см. ".format(ass_info["length"]) + output_message += "\nНаразі ваша дупенція становить: {0} см. ".format(ass_info.length) - end_time = int(time.time()) + random.randint(3600, 86400) + end_time = int(time()) + randint(3600, 72000) # from 1 hour to 20 hours - last_time = end_time - int(time.time()) + last_time = end_time - int(time()) if last_time >= 0: minutes = (last_time // 60) - (last_time // 3600) * 60 @@ -120,12 +134,12 @@ def ass_main(ass_info, database, group_id): output_message += "Продовжуй грати через {0} год., {1} хв.".format(hours, minutes) database.execute(""" UPDATE `{0}` SET length={1}, endtime={2}, spamcount=0 WHERE user_id={3} - """.format(group_id, ass_info["length"], end_time, ass_info["id"])) + """.format(group_id, ass_info.length, end_time, ass_info.id)) return output_message -if "list" not in os.listdir("."): +if not path.exists("list"): database = sqlite3.connect("list") database.execute(""" CREATE TABLE `reports` ( @@ -153,18 +167,31 @@ def ass_main(ass_info, database, group_id): @dp.message_handler(commands=["ass"]) async def ass(message: types.Message): - if message.chat["type"] == "private": # if write /ass in private messages + ''' + This function is frontend and it takes (group_id, user_id, username, first_name) + for a database's row. That's a main script for playing: it's generates random number and influence + on length, counts spam count and send to ban bad users. + ''' + + if message.from_user.is_bot: # ignore bots + return + + if message.chat.type == "private": # if write /ass in private messages await message.answer("Я працюю лише в группах!") else: # working in a group - database = sqlite3.connect("list") - group_id = message.chat["id"] * -1 - user_id = message.from_user["id"] - username = message.from_user["username"] - first_name = message.from_user["first_name"] + group_id = message.chat.id * -1 + user_id = message.from_user.id + username = message.from_user.username + first_name = message.from_user.first_name + + database = sqlite3.connect("list") try: # if group's table exists - database.execute("SELECT * FROM `%d`" % group_id) + cursor = database.execute(""" + SELECT * FROM `{0}` WHERE user_id={1} + """.format(group_id, user_id)) + ass_info = cursor.fetchone() except sqlite3.OperationalError: # creating table with name by group_id @@ -178,37 +205,39 @@ async def ass(message: types.Message): spamcount INTEGER NOT NULL, blacklisted BOOLEAN NOT NULL );""" % group_id) - print("[+] Table with name '%d' (%s) created successfully!" % (group_id, message.chat["title"])) - try: + print("[+] Table with name '%d' (%s) created successfully!" % (group_id, message.chat.title)) - database.execute(""" - INSERT INTO `groups_name` (group_id, group_name) - VALUES (?,?) - """, (group_id, message.chat["title"])) + cursor = database.execute(""" + SELECT * FROM `{0}` WHERE user_id={1} + """.format(group_id, user_id)) + ass_info = cursor.fetchone() - except sqlite3.OperationalError: + try: - database.execute(""" - CREATE TABLE `groups_name` ( - group_id INTEGER NOT NULL, - group_name VARCHAR(255) NOT NULL - ) - """) - database.execute(""" - INSERT INTO `groups_name` (group_id, group_name) - VALUES (?,?) - """, (group_id, message.chat["title"])) + database.execute(""" + INSERT INTO `groups_name` (group_id, group_name) + VALUES (?,?) + """, (group_id, message.chat.title)) - print("[+] Table `groups_name` created and row wasa added successfully!") + except sqlite3.OperationalError: + + database.execute(""" + CREATE TABLE `groups_name` ( + group_id INTEGER NOT NULL, + group_name VARCHAR(255) NOT NULL + ) + """) + database.execute(""" + INSERT INTO `groups_name` (group_id, group_name) + VALUES (?,?) + """, (group_id, message.chat.title)) + + print("[+] Table `groups_name` created and row was added successfully!") database.commit() # if user exists in database - cursor = database.execute(""" - SELECT * FROM `{0}` WHERE user_id={1} - """.format(group_id, user_id)) - ass_info = cursor.fetchone() if ass_info is None: # if user didn't be registered in the game if username is None: # if user doesn't have username @@ -234,15 +263,17 @@ async def ass(message: types.Message): if ass_info[6]: # if already blacklisted await message.reply("%s, дружок, ти вже награвся, шуруй звідси." % first_name) else: # if not blacklisted - if int(time.time()) >= ass_info[4]: # if last_time already pasted + if int(time()) >= ass_info[4]: # if last_time already pasted await message.reply(ass_main(ass_info, database, group_id)) else: - if ass_info[5] == 800000: # if spamcount == 8 + if ass_info[5] == 8: # if spamcount == 8 -> blacklisted database.execute(""" UPDATE `{0}` SET blacklisted=1, length=0 WHERE user_id={1} """.format(group_id, user_id)) await message.reply( - "%s, я тобі попку збільшую, а ти мені спамиш. Мені взагалі-то теж не солодко постійно вам попу міряти. Все, дружок, тепер ти мене не будеш зайобувати — ти в муті." % first_name) + "%s, я тобі попку збільшую, а ти мені спамиш. Мені взагалі-то теж не солодко постійно вам попу міряти. Все, дружок, тепер ти мене не будеш зайобувати — ти в муті." + % first_name + ) else: await message.reply(ass_main(ass_info, database, group_id)) @@ -252,9 +283,17 @@ async def ass(message: types.Message): @dp.message_handler(lambda message: message.text[:3] == "/bl") async def show_blacklisted_users(message: types.Message): - if message.from_user["id"] in config.SUPER_USERS: # if is admin + ''' + This function shows all banned users in a group + /bl :user_id: Group ID + ''' + + if message.from_user.is_bot: # ignore bots + return + + if message.from_user.id in SUPER_USERS: # if is admin group_id = message.text[4:] - print(message.chat["id"]) + if group_id == "": await message.reply("Ти забув ввести ID группи!") elif len(group_id) < 5: @@ -289,7 +328,14 @@ async def show_blacklisted_users(message: types.Message): @dp.message_handler(commands=["show_groups"]) async def show_groups(message: types.Message): - if message.from_user["id"] in config.SUPER_USERS: + ''' + This function shows all registered in the game groups (its id and its name) + ''' + + if message.from_user.is_bot: # ignore bots + return + + if message.from_user.id in SUPER_USERS: database = sqlite3.connect("list") # cursorObj = database.cursor() @@ -297,19 +343,23 @@ async def show_groups(message: types.Message): try: groups_info = database.cursor().execute("SELECT * FROM `groups_name`").fetchall() except sqlite3.OperationalError: + print("[!] The table `groups_name` doesn't exist or was deleted, created new one") database.execute(""" CREATE TABLE `groups_name` ( group_id INTEGER NOT NULL, group_name VARCHAR(255) NOT NULL ) """) + database.execute(""" INSERT INTO `groups_name` (group_id, group_name) VALUES (?,?) - """, (message.chat["id"]*-1, message.chat["title"]) + """, (message.chat.id *-1, message.chat.title) ) groups_info = database.cursor().execute("SELECT * FROM `groups_name`").fetchall() + database.close() + groups_dict = dict() for group in groups_info: @@ -317,7 +367,7 @@ async def show_groups(message: types.Message): # table_list = [x[0] for x in cursorObj.fetchall() if x[0] not in ["reports","groups_name"]] - database.close() + output_message = "💁TABLES\n"+"="*16+"\n" for key in groups_dict.keys(): @@ -328,7 +378,14 @@ async def show_groups(message: types.Message): # SHOW REPORTS FROM TABLE `reports` @dp.message_handler(commands=["show_reports"]) async def show_reports(message: types.Message): - if message.from_user["id"] in config.SUPER_USERS: + ''' + This function show all rows from table `reports` and send it in one message + ''' + + if message.from_user.is_bot: # ignore bots + return + + if message.from_user.id in SUPER_USERS: database = sqlite3.connect("list") cursor = database.execute("SELECT * FROM `reports`") @@ -337,16 +394,25 @@ async def show_reports(message: types.Message): output_message = "USER_ID : USERNAME : NAME : MESSAGE\n" for user in users: output_message += f"🟥 {user[2]} : {user[3]} : {user[4]} : {user[5]}\n" - database.close() await message.reply(output_message) else: await message.reply("Ще нема звітів") + database.close() @dp.message_handler(lambda message: message.text[:4] == "/ban") async def ban(message: types.Message): - if message.from_user["id"] in config.SUPER_USERS: # if is admin - if message.chat["type"] == "private": + ''' + This header reads "/ban" string and after a space user id + after that updates user's column "blacklisted" to 1 (user will be banned) + + :param message.text[5:]: user id + ''' + if message.from_user.is_bot: # ignore bots + return + + if message.from_user.id in SUPER_USERS: # if is admin + if message.chat.type == "private": await message.answer("Працює лишу у групах!") else: if not message.text[5:]: @@ -354,7 +420,7 @@ async def ban(message: types.Message): else: try: user_id = int(message.text[5:]) - group_id = message.chat["id"] * -1 + group_id = message.chat.id * -1 database = sqlite3.connect("list") # if user exists @@ -371,7 +437,7 @@ async def ban(message: types.Message): database.execute(f""" INSERT INTO `{group_id}` (user_id,username,name,length,endtime,spamcount,blacklisted) VALUES (?,?,?,?,?,?,?) - """, (user_id, message.from_user["username"], message.from_user["first_name"], 0, 0, 0, 1) + """, (user_id, message.from_user.username, message.from_user.first_name, 0, 0, 0, 1) ) database.commit() @@ -383,8 +449,16 @@ async def ban(message: types.Message): @dp.message_handler(lambda message: message.text[:3] == "/ub") async def unban(message: types.Message): - if message.from_user["id"] in config.SUPER_USERS: # if is admin - if message.chat["type"] == "private": + ''' + This handler unban user by the argument (set blacklisted to 0) + + :user_id: user's id + ''' + if message.from_user.is_bot: # ignore bots + return + + if message.from_user.id in SUPER_USERS: # if is admin + if message.chat.type == "private": await message.answer("Працює лишу у групах!") else: if not message.text[4:]: @@ -393,7 +467,7 @@ async def unban(message: types.Message): database = sqlite3.connect("list") database.execute(""" UPDATE `{0}` SET blacklisted=0, spamcount=0 WHERE user_id={1} - """.format(message.chat["id"] * -1, message.text[4:])) + """.format(message.chat.id * -1, message.text[4:])) database.commit() database.close() @@ -404,6 +478,14 @@ async def unban(message: types.Message): # REPORT "message" @dp.message_handler(lambda message: message.text[:2] == "/r") async def report(message: types.Message): + ''' + This handler reads your message after "/r " and write it in the table `reports` + + :param message.text[3:] + ''' + if message.from_user.is_bot: # ignore bots + return + if len(message.text[3:]) < 10: if len(message.text[3:].strip()) == 0: await message.reply("Ти забув уввести свій звіт!") @@ -411,17 +493,17 @@ async def report(message: types.Message): await message.reply("Звіт дуже малий!") elif message.text[2] == "@": await message.reply("Невірний формат!") + elif "--" in message.text or "#" in message.text: + await message.reply("Невірний формат!") else: - if not message.chat["title"] is None: - data = (message.chat["id"] * -1, message.chat["title"], - message.from_user["id"], message.from_user["username"], - message.from_user["first_name"], message.text[3:]) - else: + data = [message.chat.id * -1, message.chat.title, + message.from_user.id, message.from_user.username, + message.from_user.first_name, message.text[3:]] - data = (message.chat["id"] * -1, "Личные сообщения", - message.from_user["id"], message.from_user["username"], - message.from_user["first_name"], message.text[3:]) + # if it's personal message then message.chat will be marked "Personal message" + if data[1] is None: + data[1] = "Личные сообщения" database = sqlite3.connect("list") try: @@ -454,7 +536,13 @@ async def report(message: types.Message): # CLEAR ALL REPORTS FROM TABLE `reports` @dp.message_handler(commands=["clear_reports"]) async def clear_reports(message: types.Message): - if message.from_user["id"] in config.SUPER_USERS: + ''' + This function delete all writes in the table `reports` by + ''' + if message.from_user.is_bot: # ignore bots + return + + if message.from_user.id in SUPER_USERS: database = sqlite3.connect("list") database.execute(""" DELETE FROM `reports` @@ -468,14 +556,20 @@ async def clear_reports(message: types.Message): # show statistics of playing user @dp.message_handler(commands=["statistic"]) async def statistic(message: types.Message): - if "private" == message.chat["type"]: + ''' + This handler make and send an output message with user descending users by length + ''' + if message.from_user.is_bot: # ignore bots + return + + if message.chat.type == "private": await message.answer("Працює лише у групах!") else: database = sqlite3.connect("list") try: cursor = database.execute(""" SELECT * FROM `{0}` ORDER BY length DESC - """.format(message.chat["id"] * -1)) + """.format(message.chat.id * -1)) users_data = cursor.fetchall() except sqlite3.OperationalError: await message.reply("Нема гравців! Стань першим!") @@ -514,12 +608,15 @@ async def statistic(message: types.Message): # a user leaves the game @dp.message_handler(commands=["leave"]) async def leave(message: types.Message): - if message.chat["type"] != "private": # if message was gotten in a group + if message.from_user.is_bot: # ignore bots + return + + if message.chat.type != "private": # if message was gotten in a group database = sqlite3.connect("list") cursor = database.execute(""" SELECT * FROM `{0}` WHERE user_id={1} - """.format(message.chat["id"] * -1, message.from_user["id"])) + """.format(message.chat.id * -1, message.from_user.id)) ass_info = cursor.fetchone() if ass_info: # if user isn't registered @@ -528,7 +625,7 @@ async def leave(message: types.Message): else: # if user isn't blacklisted database.execute(""" DELETE FROM `{0}` WHERE user_id={1} - """.format(message.chat["id"] * -1, message.from_user["id"])) + """.format(message.chat.id * -1, message.from_user.id)) await message.reply("Ти покинув гру! Шкода такий гарний зад.") else: # if user isn't registered await message.reply("Ти не зарегестрований у грі!") @@ -538,47 +635,48 @@ async def leave(message: types.Message): await message.answer("Працює лише у групах!") -""" -@dp.message_handler(commands=["menu"]) -async def menu(message: types.Message): - keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True) - - keyboard.row( - types.KeyboardButton(text="/ass"), - types.KeyboardButton(text="/leave"), - ) - - keyboard.row( - types.KeyboardButton(text="/help"), - types.KeyboardButton(text="/statistic") - ) - - await message.reply("Звичайно, друже: ", reply_markup=keyboard) -""" - - -# shows 'start' message @dp.message_handler(commands=["start"]) async def start(message: types.Message): + ''' + Send start message from variable 'content' + ''' + if message.from_user.is_bot: # ignore bots + return + await message.reply(content["start"]) -# shows 'about' message @dp.message_handler(commands=["about"]) async def about(message: types.Message): + ''' + Send about message from variable 'content' + ''' + if message.from_user.is_bot: # ignore bots + return + await message.reply(content["about"]) -# shows 'help' message @dp.message_handler(commands=["help"]) async def user_help(message: types.Message): + ''' + Send help message from variable 'content' + ''' + if message.from_user.is_bot: # ignore bots + return + await message.reply(content["help"]) -# shows 'admin_help' message only for super_users @dp.message_handler(commands=["admin_help"]) async def admin_help(message: types.Message): - if message.from_user["id"] in config.SUPER_USERS: + ''' + Send admin_help message from variable 'content' + ''' + if message.from_user.is_bot: # ignore bots + return + + if message.from_user.id in SUPER_USERS: await message.reply(content["admin_help"])