Создал(а) 'main'

main
ramjm 1 month ago
parent fa574f38f9
commit 5ff65c138f

161
main

@ -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…
Cancel
Save