Создал(а) 'main'
This commit is contained in:
parent
fa574f38f9
commit
5ff65c138f
161
main
Normal file
161
main
Normal file
@ -0,0 +1,161 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import json
|
||||
import datetime
|
||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||
import pytz # Импортируем pytz
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
from pathlib import Path
|
||||
dotenv_path = f"{Path(__file__).parent.resolve()}/.env"
|
||||
load_dotenv(dotenv_path=dotenv_path)
|
||||
|
||||
intents = discord.Intents.default()
|
||||
intents.voice_states = True # Включаем интенты для отслеживания голосовых состояний
|
||||
intents.messages = True
|
||||
intents.message_content = True
|
||||
intents.members = True
|
||||
|
||||
bot = commands.Bot(command_prefix='!', intents=intents)
|
||||
|
||||
# Путь к файлу для хранения истории
|
||||
history_file = 'logs/voice_history.json'
|
||||
# Устанавливаем временную зону для Москвы
|
||||
moscow_tz = pytz.timezone('Europe/Moscow')
|
||||
backup_file = f'logs/voice_history_{datetime.datetime.now(moscow_tz).date()}.json'
|
||||
# Словарь для хранения истории подключений и отключений пользователей по серверам и каналам
|
||||
voice_history = {}
|
||||
|
||||
#===================[WORK WITH DB]======================================
|
||||
def load_voice_history():
|
||||
"""Загружает историю голосовых подключений из файла."""
|
||||
global voice_history
|
||||
if os.path.exists(history_file):
|
||||
with open(history_file, 'r', encoding='utf-8') as f:
|
||||
try:
|
||||
voice_history = json.load(f)
|
||||
except:
|
||||
voice_history = {}
|
||||
|
||||
def save_voice_history():
|
||||
"""Сохраняет историю голосовых подключений в файл."""
|
||||
with open(history_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(voice_history, f, ensure_ascii=False, indent=4)
|
||||
|
||||
def backup_voice_history():
|
||||
"""Создает резервную копию истории голосовых подключений."""
|
||||
if os.path.exists(history_file):
|
||||
with open(history_file, 'r', encoding='utf-8') as f:
|
||||
data = f.read()
|
||||
with open(backup_file, 'w', encoding='utf-8') as f:
|
||||
f.write(data)
|
||||
with open(history_file, 'w', encoding='utf-8') as f:
|
||||
f.write("{}")
|
||||
#===================[WORK WITH DB]======================================
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
load_voice_history() # Загружаем историю при запуске бота
|
||||
print(f'Бот {bot.user} запущен!')
|
||||
# Настраиваем планировщик
|
||||
scheduler = AsyncIOScheduler()
|
||||
scheduler.add_job(backup_voice_history, 'cron', hour=17, minute=47) # Запланировать на 00:00
|
||||
scheduler.start()
|
||||
|
||||
@bot.event
|
||||
async def on_voice_state_update(member, before, after):
|
||||
guild_id = str(member.guild.id) # Получаем ID сервера как строку
|
||||
channel_id = str(after.channel.id) if after.channel else str(before.channel.id) if before.channel else None
|
||||
|
||||
# Инициализируем историю для сервера, если её нет
|
||||
if guild_id not in voice_history:
|
||||
voice_history[guild_id] = {}
|
||||
|
||||
# Инициализируем историю для канала, если её нет
|
||||
if channel_id not in voice_history[guild_id]:
|
||||
voice_history[guild_id][channel_id] = []
|
||||
|
||||
# Если пользователь подключился к голосовому каналу
|
||||
if before.channel is None and after.channel is not None:
|
||||
join_time = datetime.datetime.now(moscow_tz) # Получаем текущее время в Москве
|
||||
voice_history[guild_id][channel_id].append({
|
||||
'user_id': member.id,
|
||||
'join_time': join_time.isoformat(), # Сохраняем время в формате ISO
|
||||
'leave_time': None
|
||||
})
|
||||
save_voice_history() # Сохраняем историю после обновления
|
||||
|
||||
# Если пользователь отключился от голосового канала
|
||||
elif before.channel is not None and after.channel is None:
|
||||
leave_time = datetime.datetime.now(moscow_tz) # Получаем текущее время в Москве
|
||||
for record in voice_history[guild_id][channel_id]:
|
||||
if record['user_id'] == member.id and record['leave_time'] is None:
|
||||
record['leave_time'] = leave_time.isoformat() # Обновляем последнее подключение
|
||||
break
|
||||
save_voice_history() # Сохраняем историю после обновления
|
||||
|
||||
|
||||
|
||||
@bot.command(name="log")
|
||||
async def _log(ctx, channel_name: str):
|
||||
"""Команда для вывода логов о подключениях и отключениях пользователей в определённом голосовом канале за день."""
|
||||
load_voice_history()
|
||||
guild_id = str(ctx.guild.id) # Получаем ID сервера как строку
|
||||
|
||||
# Получаем список всех голосовых каналов на сервере
|
||||
voice_channels = {channel.name: str(channel.id) for channel in ctx.guild.voice_channels}
|
||||
|
||||
# Проверяем, существует ли канал с таким именем
|
||||
channel_id = voice_channels.get(channel_name)
|
||||
if not channel_id:
|
||||
await ctx.send(f"Канал с именем '{channel_name}' не найден.")
|
||||
return
|
||||
|
||||
# Проверяем, есть ли записи для этого канала в истории
|
||||
if guild_id not in voice_history or channel_id not in voice_history[guild_id]:
|
||||
await ctx.send("Нет записей о подключениях и отключениях.")
|
||||
return
|
||||
|
||||
today = datetime.datetime.now(moscow_tz).date()
|
||||
log_messages = []
|
||||
|
||||
for record in voice_history[guild_id][channel_id]:
|
||||
user_id = record['user_id']
|
||||
join_time = datetime.datetime.fromisoformat(record['join_time']) # Преобразуем обратно в datetime
|
||||
leave_time = record['leave_time']
|
||||
|
||||
try:
|
||||
member = await ctx.guild.fetch_member(user_id) # Получаем участника по ID
|
||||
member_mention = member.mention
|
||||
except discord.NotFound:
|
||||
await ctx.send('Пользователь не найден.')
|
||||
continue # Пропускаем, если пользователь не найден
|
||||
except discord.Forbidden:
|
||||
await ctx.send('У меня нет прав для получения информации о пользователе.')
|
||||
continue # Пропускаем, если нет прав
|
||||
except discord.HTTPException:
|
||||
await ctx.send('Произошла ошибка при получении информации о пользователе.')
|
||||
continue # Пропускаем, если произошла ошибка
|
||||
|
||||
if leave_time is None: # Если пользователь все еще в голосовом канале
|
||||
duration = datetime.datetime.now(moscow_tz) - join_time
|
||||
log_messages.append(
|
||||
f"{member_mention} подключен к каналу с {join_time.strftime('%Y-%m-%d %H:%M:%S')}\n"\
|
||||
f"(продолжительность: {duration})\n")
|
||||
else:
|
||||
leave_time = datetime.datetime.fromisoformat(leave_time) # Преобразуем обратно в datetime
|
||||
if leave_time.date() == today: # Проверяем, что отключение произошло сегодня
|
||||
duration = leave_time - join_time
|
||||
log_messages.append(
|
||||
f"{member_mention} подключен к каналу с {join_time.strftime('%Y-%m-%d %H:%M:%S')}\n"\
|
||||
f"отключен с {leave_time.strftime('%Y-%m-%d %H:%M:%S')}"\
|
||||
f"\n(продолжительность: {duration})\n"
|
||||
)
|
||||
|
||||
if log_messages:
|
||||
await ctx.send("\n".join(log_messages))
|
||||
else:
|
||||
await ctx.send(f"Нет записей о подключениях и отключениях в канале '{channel_name}' за сегодня.")
|
||||
|
||||
|
||||
bot.run(os.getenv("token"))
|
Loading…
Reference in New Issue
Block a user