Снижено дублирование кода, связанного с выводом статистики.
Дополнительная логика формирования списка молчунов перенесена в SQL-запрос.
This commit is contained in:
parent
ecfc83d5ad
commit
d914ee5a00
3 changed files with 58 additions and 64 deletions
22
database.py
22
database.py
|
|
@ -87,7 +87,7 @@ class Database:
|
|||
|
||||
def get_top_messages_today(self, chat_id: int):
|
||||
self.cursor.execute("""
|
||||
SELECT user_id, messages_today FROM users
|
||||
SELECT user_id, messages_today AS value FROM users
|
||||
WHERE chat_id = ? AND messages_today > 0
|
||||
ORDER BY messages_today DESC
|
||||
""", (chat_id,))
|
||||
|
|
@ -95,23 +95,29 @@ class Database:
|
|||
|
||||
def get_top_messages_month(self, chat_id: int):
|
||||
self.cursor.execute("""
|
||||
SELECT user_id, messages_month FROM users
|
||||
SELECT user_id, messages_month AS value FROM users
|
||||
WHERE chat_id = ? AND messages_month > 0
|
||||
ORDER BY messages_month DESC
|
||||
""", (chat_id,))
|
||||
return self.cursor.fetchall()
|
||||
|
||||
def get_top_silent(self, chat_id: int, threshold_time: int):
|
||||
def get_top_silent(self, chat_id: int, threshold_days: int):
|
||||
# noinspection SpellCheckingInspection
|
||||
self.cursor.execute("""
|
||||
SELECT user_id, last_message FROM users
|
||||
WHERE chat_id = ? AND last_message < ?
|
||||
ORDER BY last_message ASC
|
||||
""", (chat_id, threshold_time))
|
||||
SELECT user_id,
|
||||
CASE
|
||||
WHEN last_message = 0 THEN 'никогда'
|
||||
ELSE (unixepoch() - last_message) / 86400
|
||||
END AS value
|
||||
FROM users
|
||||
WHERE chat_id = ? AND value >= ?
|
||||
ORDER BY value DESC
|
||||
""", (chat_id, threshold_days))
|
||||
return self.cursor.fetchall()
|
||||
|
||||
def get_top_warnings(self, chat_id: int):
|
||||
self.cursor.execute("""
|
||||
SELECT user_id, warnings FROM users
|
||||
SELECT user_id, warnings AS value FROM users
|
||||
WHERE chat_id = ? AND warnings > 0
|
||||
ORDER BY warnings DESC
|
||||
""", (chat_id,))
|
||||
|
|
|
|||
|
|
@ -1,13 +1,32 @@
|
|||
from vkbottle import bold, italic
|
||||
from typing import List, Any
|
||||
|
||||
from vkbottle import bold, italic, API
|
||||
from vkbottle.bot import Message
|
||||
|
||||
import database
|
||||
from messages import *
|
||||
import utils
|
||||
|
||||
from labeler import labeler
|
||||
|
||||
|
||||
# top_users - массив sqlite3.Row с двумя столбцами: user_id и value
|
||||
async def format_rating(top_users: List[Any], api: API) -> str:
|
||||
top_user_ids = [user['user_id'] for user in top_users]
|
||||
users_info = await api.users.get(user_ids=top_user_ids)
|
||||
|
||||
result = ''
|
||||
i = 1
|
||||
for user in top_users:
|
||||
for info in users_info:
|
||||
if info.id == user['user_id']:
|
||||
result += '{}. {} {} - {}\n'.format(i, info.first_name, info.last_name, user['value'])
|
||||
i = i + 1
|
||||
break
|
||||
|
||||
return result
|
||||
|
||||
|
||||
# noinspection SpellCheckingInspection
|
||||
@labeler.chat_message(text="!помощь")
|
||||
async def rules_handler(message: Message):
|
||||
chat_id = message.peer_id
|
||||
|
|
@ -50,18 +69,8 @@ async def stats_today_handler(message: Message):
|
|||
await message.answer('Сегодня еще никто не писал.')
|
||||
return
|
||||
|
||||
top_user_ids = [user['user_id'] for user in top_users]
|
||||
users_info = await message.ctx_api.users.get(user_ids=top_user_ids)
|
||||
|
||||
response = bold('Статистика за сегодня') + '\n'
|
||||
i = 1
|
||||
for user in top_users:
|
||||
for info in users_info:
|
||||
if info.id == user['user_id']:
|
||||
response += '{}. {} {} - {}\n'.format(i, info.first_name, info.last_name, user['messages_today'])
|
||||
i = i + 1
|
||||
break
|
||||
|
||||
response += await format_rating(top_users, message.ctx_api)
|
||||
await message.answer(response)
|
||||
|
||||
|
||||
|
|
@ -78,18 +87,8 @@ async def stats_month_handler(message: Message):
|
|||
await message.answer('В этом месяце еще никто не писал.')
|
||||
return
|
||||
|
||||
top_user_ids = [user['user_id'] for user in top_users]
|
||||
users_info = await message.ctx_api.users.get(user_ids=top_user_ids)
|
||||
|
||||
response = bold('Статистика за месяц') + '\n'
|
||||
i = 1
|
||||
for user in top_users:
|
||||
for info in users_info:
|
||||
if info.id == user['user_id']:
|
||||
response += '{}. {} {} - {}\n'.format(i, info.first_name, info.last_name, user['messages_month'])
|
||||
i = i + 1
|
||||
break
|
||||
|
||||
response += await format_rating(top_users, message.ctx_api)
|
||||
await message.answer(response)
|
||||
|
||||
|
||||
|
|
@ -101,29 +100,13 @@ async def silent_handler(message: Message):
|
|||
await message.answer(MESSAGE_CHAT_NOT_ACTIVE)
|
||||
return
|
||||
|
||||
now = utils.posix_time()
|
||||
threshold = now - 14 * 24 * 3600
|
||||
top_users = database.DB.get_top_silent(message.peer_id, threshold)
|
||||
top_users = database.DB.get_top_silent(chat_id, 14)
|
||||
if len(top_users) == 0:
|
||||
await message.answer('Молчунов нет. Все молодцы!')
|
||||
return
|
||||
|
||||
top_user_ids = [user['user_id'] for user in top_users]
|
||||
users_info = await message.ctx_api.users.get(user_ids=top_user_ids)
|
||||
|
||||
response = bold('Молчуны чата') + ' (не писали больше 2 недель)\n'
|
||||
i = 1
|
||||
for user in top_users:
|
||||
for info in users_info:
|
||||
if info.id == user['user_id']:
|
||||
if user['last_message'] == 0:
|
||||
response += '{}. {} {} - никогда\n'.format(i, info.first_name, info.last_name)
|
||||
else:
|
||||
days_silent = round((now - user['last_message']) / 3600 / 24)
|
||||
response += '{}. {} {} - {} дней\n'.format(i, info.first_name, info.last_name, days_silent)
|
||||
i = i + 1
|
||||
break
|
||||
|
||||
response += await format_rating(top_users, message.ctx_api)
|
||||
await message.answer(response)
|
||||
|
||||
|
||||
|
|
@ -140,18 +123,8 @@ async def warnings_handler(message: Message):
|
|||
await message.answer('Пока все спокойно. Продолжайте в том же духе.')
|
||||
return
|
||||
|
||||
top_user_ids = [user['user_id'] for user in top_users]
|
||||
users_info = await message.ctx_api.users.get(user_ids=top_user_ids)
|
||||
|
||||
response = bold('Участники с предупреждениями') + '\n'
|
||||
i = 1
|
||||
for user in top_users:
|
||||
for info in users_info:
|
||||
if info.id == user['user_id']:
|
||||
response += '{}. {} {} - {}\n'.format(i, info.first_name, info.last_name, user['warnings'])
|
||||
i = i + 1
|
||||
break
|
||||
|
||||
response += await format_rating(top_users, message.ctx_api)
|
||||
await message.answer(response)
|
||||
|
||||
|
||||
|
|
|
|||
21
tasks.py
21
tasks.py
|
|
@ -2,17 +2,32 @@ import datetime
|
|||
import traceback
|
||||
|
||||
from asyncio import sleep
|
||||
from vkbottle import API
|
||||
from vkbottle import API, bold
|
||||
|
||||
import database
|
||||
from handlers.user import format_rating
|
||||
from messages import *
|
||||
|
||||
|
||||
def reset_counters(reset_month: bool):
|
||||
async def reset_counters(reset_month: bool, api: API):
|
||||
database.DB.reset_messages_today()
|
||||
print('Дневные счетчики сброшены.')
|
||||
|
||||
if reset_month:
|
||||
for chat in database.DB.get_chats():
|
||||
if chat['active'] == 0:
|
||||
continue
|
||||
|
||||
top_users = database.DB.get_top_messages_month(chat['id'])
|
||||
if len(top_users) == 0:
|
||||
continue
|
||||
|
||||
message = bold('Итоговая статистика за прошедший месяц') + '\n'
|
||||
message += await format_rating(top_users, api)
|
||||
# noinspection PyArgumentList
|
||||
await api.messages.send(random_id=0, peer_id=chat['id'],
|
||||
message=str(message), format_data=message.as_raw_data())
|
||||
|
||||
database.DB.reset_messages_month()
|
||||
print('Месячные счетчики сброшены.')
|
||||
|
||||
|
|
@ -76,7 +91,7 @@ async def daily_maintenance_task(api: API):
|
|||
await wait_until(target_datetime)
|
||||
|
||||
try:
|
||||
reset_counters(target_datetime.day == 1)
|
||||
await reset_counters(target_datetime.day == 1, api)
|
||||
await check_birthdays(api)
|
||||
except Exception:
|
||||
print(traceback.format_exc())
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue