Снижено дублирование кода, связанного с выводом статистики.
Дополнительная логика формирования списка молчунов перенесена в 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):
|
def get_top_messages_today(self, chat_id: int):
|
||||||
self.cursor.execute("""
|
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
|
WHERE chat_id = ? AND messages_today > 0
|
||||||
ORDER BY messages_today DESC
|
ORDER BY messages_today DESC
|
||||||
""", (chat_id,))
|
""", (chat_id,))
|
||||||
|
|
@ -95,23 +95,29 @@ class Database:
|
||||||
|
|
||||||
def get_top_messages_month(self, chat_id: int):
|
def get_top_messages_month(self, chat_id: int):
|
||||||
self.cursor.execute("""
|
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
|
WHERE chat_id = ? AND messages_month > 0
|
||||||
ORDER BY messages_month DESC
|
ORDER BY messages_month DESC
|
||||||
""", (chat_id,))
|
""", (chat_id,))
|
||||||
return self.cursor.fetchall()
|
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("""
|
self.cursor.execute("""
|
||||||
SELECT user_id, last_message FROM users
|
SELECT user_id,
|
||||||
WHERE chat_id = ? AND last_message < ?
|
CASE
|
||||||
ORDER BY last_message ASC
|
WHEN last_message = 0 THEN 'никогда'
|
||||||
""", (chat_id, threshold_time))
|
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()
|
return self.cursor.fetchall()
|
||||||
|
|
||||||
def get_top_warnings(self, chat_id: int):
|
def get_top_warnings(self, chat_id: int):
|
||||||
self.cursor.execute("""
|
self.cursor.execute("""
|
||||||
SELECT user_id, warnings FROM users
|
SELECT user_id, warnings AS value FROM users
|
||||||
WHERE chat_id = ? AND warnings > 0
|
WHERE chat_id = ? AND warnings > 0
|
||||||
ORDER BY warnings DESC
|
ORDER BY warnings DESC
|
||||||
""", (chat_id,))
|
""", (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
|
from vkbottle.bot import Message
|
||||||
|
|
||||||
import database
|
import database
|
||||||
from messages import *
|
from messages import *
|
||||||
import utils
|
|
||||||
|
|
||||||
from labeler import labeler
|
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="!помощь")
|
@labeler.chat_message(text="!помощь")
|
||||||
async def rules_handler(message: Message):
|
async def rules_handler(message: Message):
|
||||||
chat_id = message.peer_id
|
chat_id = message.peer_id
|
||||||
|
|
@ -50,18 +69,8 @@ async def stats_today_handler(message: Message):
|
||||||
await message.answer('Сегодня еще никто не писал.')
|
await message.answer('Сегодня еще никто не писал.')
|
||||||
return
|
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'
|
response = bold('Статистика за сегодня') + '\n'
|
||||||
i = 1
|
response += await format_rating(top_users, message.ctx_api)
|
||||||
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
|
|
||||||
|
|
||||||
await message.answer(response)
|
await message.answer(response)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -78,18 +87,8 @@ async def stats_month_handler(message: Message):
|
||||||
await message.answer('В этом месяце еще никто не писал.')
|
await message.answer('В этом месяце еще никто не писал.')
|
||||||
return
|
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'
|
response = bold('Статистика за месяц') + '\n'
|
||||||
i = 1
|
response += await format_rating(top_users, message.ctx_api)
|
||||||
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
|
|
||||||
|
|
||||||
await message.answer(response)
|
await message.answer(response)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -101,29 +100,13 @@ async def silent_handler(message: Message):
|
||||||
await message.answer(MESSAGE_CHAT_NOT_ACTIVE)
|
await message.answer(MESSAGE_CHAT_NOT_ACTIVE)
|
||||||
return
|
return
|
||||||
|
|
||||||
now = utils.posix_time()
|
top_users = database.DB.get_top_silent(chat_id, 14)
|
||||||
threshold = now - 14 * 24 * 3600
|
|
||||||
top_users = database.DB.get_top_silent(message.peer_id, threshold)
|
|
||||||
if len(top_users) == 0:
|
if len(top_users) == 0:
|
||||||
await message.answer('Молчунов нет. Все молодцы!')
|
await message.answer('Молчунов нет. Все молодцы!')
|
||||||
return
|
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'
|
response = bold('Молчуны чата') + ' (не писали больше 2 недель)\n'
|
||||||
i = 1
|
response += await format_rating(top_users, message.ctx_api)
|
||||||
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
|
|
||||||
|
|
||||||
await message.answer(response)
|
await message.answer(response)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -140,18 +123,8 @@ async def warnings_handler(message: Message):
|
||||||
await message.answer('Пока все спокойно. Продолжайте в том же духе.')
|
await message.answer('Пока все спокойно. Продолжайте в том же духе.')
|
||||||
return
|
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'
|
response = bold('Участники с предупреждениями') + '\n'
|
||||||
i = 1
|
response += await format_rating(top_users, message.ctx_api)
|
||||||
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
|
|
||||||
|
|
||||||
await message.answer(response)
|
await message.answer(response)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
21
tasks.py
21
tasks.py
|
|
@ -2,17 +2,32 @@ import datetime
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from asyncio import sleep
|
from asyncio import sleep
|
||||||
from vkbottle import API
|
from vkbottle import API, bold
|
||||||
|
|
||||||
import database
|
import database
|
||||||
|
from handlers.user import format_rating
|
||||||
from messages import *
|
from messages import *
|
||||||
|
|
||||||
|
|
||||||
def reset_counters(reset_month: bool):
|
async def reset_counters(reset_month: bool, api: API):
|
||||||
database.DB.reset_messages_today()
|
database.DB.reset_messages_today()
|
||||||
print('Дневные счетчики сброшены.')
|
print('Дневные счетчики сброшены.')
|
||||||
|
|
||||||
if reset_month:
|
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()
|
database.DB.reset_messages_month()
|
||||||
print('Месячные счетчики сброшены.')
|
print('Месячные счетчики сброшены.')
|
||||||
|
|
||||||
|
|
@ -76,7 +91,7 @@ async def daily_maintenance_task(api: API):
|
||||||
await wait_until(target_datetime)
|
await wait_until(target_datetime)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
reset_counters(target_datetime.day == 1)
|
await reset_counters(target_datetime.day == 1, api)
|
||||||
await check_birthdays(api)
|
await check_birthdays(api)
|
||||||
except Exception:
|
except Exception:
|
||||||
print(traceback.format_exc())
|
print(traceback.format_exc())
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue