Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

Добавил бота функцию "карма". #26

Open
wants to merge 5 commits into
base: work_in_groups
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .env.dist → .env
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Telegram API Token
BOT_TOKEN=
BOT_TOKEN=token

# Не надо использовать пробел после ","
ADMINS_ID=123456789,987654321
ADMINS_ID=ID

# Указываем пропускать ли боту апдейты при запуске
SKIP_UPDATES=False
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ celerybeat.pid
*.sage.py

# Environments
.env
.env.dist
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

нет, нахрена это? dist - файл-пример

.venv
env/
venv/
Expand Down
2 changes: 2 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
async def on_startup(dp):
await set_default_commands(dp)
await on_startup_notify(dp)

try:
db.create_table_stickers()
db.create_table_karma_users()
except Exception as err:
print(err)
logger.info("Бот запущен")
Expand Down
10 changes: 10 additions & 0 deletions data/cache_karma.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@


# тут мы будем хранить данные для того, чтобы не наргуржать базу данных не нужной информацией.
"""
format
{message_id: user_id}

"""
reply_message_id_user = {}

Binary file modified data/main.db
Binary file not shown.
3 changes: 2 additions & 1 deletion filters/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from aiogram import Dispatcher
from loguru import logger


from .admin_filter import IsPrivateAdmin
from .user_filters import IsContributor
from .chat_filters import IsGroup
from .chat_filters import IsPrivate
Expand All @@ -23,3 +23,4 @@ def setup(dp: Dispatcher):
dp.filters_factory.bind(IsContributor)
dp.filters_factory.bind(IsGroup)
dp.filters_factory.bind(IsPrivate)
dp.filters_factory.bind(IsPrivateAdmin)
42 changes: 42 additions & 0 deletions filters/access_karma.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from aiogram import types
from aiogram.dispatcher.filters import BoundFilter
from loguru import logger

from data.cache_karma import reply_message_id_user
from loader import db, bot


class Restriction_Karma(BoundFilter):

async def check(self, message: types.Message) -> bool:
bot_id = (await bot.get_me()).id
my_user_id = message.from_user.id
user_id_not_karma = [bot_id, my_user_id]

# чтобы нельзя было давать карму боту и самому себе
if message.reply_to_message.from_user.id in user_id_not_karma:
await message.delete()
return False

if await self._get_cached_message_value(message) is None:
await self._set_cached_message_value(message)
db.add_user(user_id=message.reply_to_message.from_user.id,
full_name=message.reply_to_message.from_user.full_name)
await message.delete()
return True

async def _set_cached_message_value(self, message: types.Message):
if not await self._get_cached_message_value(message) is None:
return
reply_message_id_user[message.reply_to_message.message_id] = message.from_user.id

async def _get_cached_message_value(self, message: types.Message):
try:
return reply_message_id_user[message.reply_to_message.message_id]
except Exception as error:
logger.info(error)





11 changes: 11 additions & 0 deletions filters/admin_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from aiogram import types
from aiogram.dispatcher.filters import BoundFilter


class IsPrivateAdmin(BoundFilter):
def __init__(self, users_id: list):
self.users_id = list(map(int, users_id))

async def check(self, message:types.Message):

return message.from_user.id in self.users_id
1 change: 1 addition & 0 deletions filters/chat_filters.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from aiogram import types
from aiogram.dispatcher.filters import BoundFilter
from loguru import logger


class IsGroup(BoundFilter):
Expand Down
2 changes: 0 additions & 2 deletions filters/is_reply.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ class IsReplyFilter(BoundFilter):
"""
Фильтр, проверяющий, явлляется ли сообщение ответом на сообщение
"""

key = "is_reply"

is_reply: bool

async def check(self, message: types.Message) -> bool:
Expand Down
1 change: 1 addition & 0 deletions handlers/essential/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .errors import dp
from .other import dp
from .metabolism import dp
from .karma import dp

__all__ = ["dp"]
72 changes: 72 additions & 0 deletions handlers/essential/karma.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import re

from aiogram import types
from aiogram.dispatcher.filters import Command, AdminFilter
from aiogram.utils.markdown import hlink, hbold

from data.cache_karma import reply_message_id_user
from data.config import ADMINS_ID
from filters import IsGroup, IsReplyFilter, IsPrivate, IsPrivateAdmin
from filters.access_karma import Restriction_Karma
from loader import dp, bot, db
from utils.misc import rate_limit
from utils.misc.karma import karma, url


@dp.message_handler(IsPrivate(), IsPrivateAdmin(ADMINS_ID), Command("clear"))
async def clear_cache_message_id_karma(message: types.Message):
size = None

if type(reply_message_id_user) is dict:
size = 144
if len(reply_message_id_user) > 8:
size += 12 * (len(reply_message_id_user) - 8)
await message.answer(f"Памяти в кэше {size}\n"
"Было очищено")
reply_message_id_user.clear()

@rate_limit(limit=0)
@dp.message_handler(IsGroup(), Command("top_karma", prefixes="!/"))
async def result_top_users(message: types.Message):
name_bot = await bot.get_me()
command_parse = re.compile(r"(!top_karma|/top_karma) ?(\d+)?")
a = command_parse.match(message.text)
limit = a.group(2)

if limit is None:
limit = 10

if int(limit) > 20:
limit = 20

list_top_users = db.select_karma_top(limit=limit)
text_messages = [f"Топ участников чата по карме: {hbold(name_bot.full_name)}"]

for count, user_object in enumerate(list_top_users, 1):
user_id, karma_user, full_name = user_object
text = f"{count}. {hlink(full_name, url(user_id))} - {karma_user} 💋"
text_messages.append(text)

await message.answer("\n".join(text_messages))

@rate_limit(limit=60)
@dp.message_handler(IsGroup(), IsReplyFilter(is_reply=True), Restriction_Karma(), text=["+", "-"])
async def give_karma_user(message: types.Message):

answer = message.text
text_with_karma = {"+": (1, "пополнил"),
"-": (-1, "понизил")}
karma(message, karma=text_with_karma[f"{answer}"][0])

user = hlink(message.from_user.first_name, message.from_user.url)
text = text_with_karma.get(answer)[1]
to_user = hlink(message.reply_to_message.from_user.first_name, message.reply_to_message.from_user.url)
get_karma = str(text_with_karma.get(answer)[0])
total_karma = db.select_karma_user(user_id=message.reply_to_message.from_user.id)[0][1] # получаем общую карму пользователя

await message.answer(R"""{user} {text} {to_user} карму на {get_karma}
Текущая карма: {total_karma}""".format(user=user,
text=text,
to_user=to_user,
get_karma=get_karma,
total_karma=total_karma))
1 change: 0 additions & 1 deletion handlers/groups/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ async def help(message: types.Message):
"/gay [цель*] - Тест на гея" "\n"
"/biba - Проверить бибу" "\n"
"/roll - Случайное число" "\n"
"/metabolism - Узнать свою суточную норму калорий" "\n"
"\n"
"{warning}".format(
header1=hbold("Основные комманды"),
Expand Down
1 change: 1 addition & 0 deletions handlers/groups/service_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ async def left_chat_member(message: types.Message):
return False

# Проверяем вышел ли пользователь сам

if message.left_chat_member.id == message.from_user.id:
await message.answer(f"{message.left_chat_member.get_mention(as_html=True)} вышел из чата.")
until_date = datetime.datetime.now() + datetime.timedelta(days=1)
Expand Down
1 change: 1 addition & 0 deletions handlers/private/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from filters import IsPrivate
from keyboards.inline import start_markup
from loader import dp
from utils.misc import rate_limit


@dp.message_handler(IsPrivate(), Command("start", prefixes="/"))
Expand Down
3 changes: 2 additions & 1 deletion middlewares/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from aiogram import Dispatcher
from loguru import logger

from .throttling import ThrottlingMiddleware

from .throttling import ThrottlingMiddleware

def setup(dp: Dispatcher):
logger.info("Подключение middlewares...")
dp.middleware.setup(ThrottlingMiddleware())

14 changes: 11 additions & 3 deletions middlewares/throttling.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,39 @@
from aiogram.dispatcher.handler import CancelHandler, current_handler
from aiogram.dispatcher.middlewares import BaseMiddleware
from aiogram.utils.exceptions import Throttled
from loguru import logger


class ThrottlingMiddleware(BaseMiddleware):
"""
Simple middleware
"""

def __init__(self, limit=DEFAULT_RATE_LIMIT, key_prefix='antiflood_'):
def __init__(self, limit=DEFAULT_RATE_LIMIT,
limit_karma=1,
key_prefix='antiflood_'):
self.rate_limit = limit
self.prefix = key_prefix

super(ThrottlingMiddleware, self).__init__()

# noinspection PyUnusedLocal
async def on_process_message(self, message: types.Message, data: dict):
handler = current_handler.get()
dispatcher = Dispatcher.get_current()

if handler:
limit = getattr(handler, 'throttling_rate_limit', self.rate_limit)
key = getattr(handler, 'throttling_key', f"{self.prefix}_{handler.__name__}")
else:
limit = self.rate_limit
key = f"{self.prefix}_message"
try:
logger.info(limit)

await dispatcher.throttle(key, rate=limit)
except Throttled as t:

await self.message_throttled(message, t)
raise CancelHandler()

Expand All @@ -42,9 +50,9 @@ async def message_throttled(self, message: types.Message, throttled: Throttled):
key = f"{self.prefix}_message"
delta = throttled.rate - throttled.delta
if throttled.exceeded_count <= 2:
service_message = await message.reply('Too many requests! ')
service_message = await message.answer('Не надо так часто.')

await asyncio.sleep(5)
await asyncio.sleep(2)
await service_message.delete()
await message.delete()
try:
Expand Down
73 changes: 65 additions & 8 deletions utils/db_api/sqlite.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import sqlite3

from loguru import logger


class Database:
def __init__(self, path_to_db="main.db"):
Expand All @@ -13,7 +15,7 @@ def execute(self, sql: str, parameters: tuple = None, fetchone=False, fetchall=F
if not parameters:
parameters = ()
connection = self.connection
connection.set_trace_callback(logger)
# connection.set_trace_callback(logger)
cursor = connection.cursor()
data = None
cursor.execute(sql, parameters)
Expand Down Expand Up @@ -55,11 +57,66 @@ def select_all_sets(self):
"""
return self.execute(sql, fetchall=True)

def create_table_karma_users(self):

"""
Создаем таблицу с название USERS_KARMA
колонки:
user_id : integer
karma: integer

"""
sql = """CREATE TABLE USERS_KARMA (

user_id INTEGER PRIMARY KEY,
karma INTEGER,
full_name varchar 255
)
"""
self.execute(sql, commit=True)

def update_karma(self, user_id: int, karma: int = 0):

# если статус update_karma = True, мы обновляем карму
now_karma = self.select_karma_user(user_id=user_id)[0][1]

now_karma += karma
sql = "UPDATE USERS_KARMA SET karma = ? WHERE user_id = ?"
return self.execute(sql, parameters=(now_karma, user_id), commit=True)

def add_user(self, user_id: int, full_name: str, karma: int = 0):
try:
sql = "INSERT INTO USERS_KARMA (user_id, full_name, karma) VALUES (?,?,?)"
self.execute(sql, parameters=(user_id, full_name, karma), commit=True)
except Exception as e:
logger.info(e)

def select_karma_user(self, user_id: int):
"""
Выводим пользователя из базы данных по юзеру
"""
sql = "SELECT * FROM USERS_KARMA WHERE user_id = ?"
return self.execute(sql, parameters=(user_id,), fetchall=True)

def select_karma_top(self, limit: int = 10):
"""
Функция в котором мы определяем количество топ пользователей
группы по набранным баллам

parameters:
limit - int , default = 10 users
"""

sql = "SELECT * FROM USERS_KARMA ORDER BY karma DESC"
setting_limit = " LIMIT " + str(limit)
sql += setting_limit

return self.execute(sql, fetchall=True)

def logger(statement):
print(f"""
_____________________________________________________
Executing:
{statement}
_____________________________________________________
""")
# def logger(statement):
# print(f"""
# _____________________________________________________
# Executing:
# {statement}
# _____________________________________________________
# """)
Loading