diff --git a/README.md b/README.md
index 0dc03e9..067b28d 100644
--- a/README.md
+++ b/README.md
@@ -12,8 +12,10 @@
Files:
+ - avatar.jpg — bot's avatar
- config.py — file with configuration parameters (TOKEN, SUPER_USERS, DEBUG)
- main.py — main file
+ - messages.json — file with bot's long messages (help, start, admin, about)
@@ -38,6 +40,9 @@
+ -
+ /start — greet the bot
+
-
/ass — start playing
@@ -53,6 +58,9 @@
-
/statistic — show top list of users
+ -
+ /about — show info about the developer
+
@@ -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"])