From cd8ed8bc5793985df2c1692072a932ceee517b95 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 8 Jul 2026 02:13:35 +0200 Subject: OPEN THE RUST GATES Signed-off-by: salmonik --- cogs/vclogs.py | 316 --------------------------------------------------------- 1 file changed, 316 deletions(-) delete mode 100644 cogs/vclogs.py (limited to 'cogs/vclogs.py') diff --git a/cogs/vclogs.py b/cogs/vclogs.py deleted file mode 100644 index 35826d4..0000000 --- a/cogs/vclogs.py +++ /dev/null @@ -1,316 +0,0 @@ -# This file is part of Senator Sperma -# Licensed under the GPL-3.0 License -# Copyright (C) 2026 Salmonik @ salmonik@tuta.io -# https://codeberg.org/salmonik/senator-sperma - -import datetime -import logging -import os -import asyncio -import discord -from discord.ext import commands -from gtts import gTTS -from cogs.voice import get_voice_manager -from cogs.utils.settings import get_volume, save_settings -from cogs.utils.database import get_connection, init_database - -import tempfile - -logger = logging.getLogger(__name__) - -init_database() - - -def load_activity_data(): - try: - with get_connection() as conn: - c = conn.cursor() - c.execute("SELECT user_id, join_time, total_active, total_afk, is_afk, afk_start, active_start, channel_name FROM voice_activity") - rows = c.fetchall() - - return { - row[0]: { - "join_time": row[1], - "total_active": row[2], - "total_afk": row[3], - "is_afk": bool(row[4]), - "afk_start": row[5], - "active_start": row[6], - "channel_name": row[7], - } - for row in rows - } - except Exception as e: - logger.error(f"Error loading voice activity: {e}") - return {} - - -def save_activity_data(data): - try: - with get_connection() as conn: - c = conn.cursor() - c.execute("PRAGMA foreign_keys = ON") - - c.execute("DELETE FROM voice_activity") - - for user_id, user_data in data.items(): - c.execute( - """INSERT INTO voice_activity (user_id, join_time, total_active, total_afk, is_afk, afk_start, active_start, channel_name) - VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", - ( - user_id, - user_data.get("join_time"), - user_data.get("total_active", 0), - user_data.get("total_afk", 0), - int(user_data.get("is_afk", False)), - user_data.get("afk_start"), - user_data.get("active_start"), - user_data.get("channel_name"), - ), - ) - conn.commit() - logger.info(f"Saved voice activity for {len(data)} users") - except Exception as e: - logger.error(f"Error saving voice activity: {e}") - - -def format_duration(seconds): - hours, remainder = divmod(int(seconds), 3600) - minutes, seconds = divmod(remainder, 60) - if hours > 0: - return f"{hours}h {minutes}m {seconds}s" - elif minutes > 0: - return f"{minutes}m {seconds}s" - return f"{seconds}s" - - -class VcLogs(commands.Cog): - def __init__(self, bot): - self.bot = bot - self._voice_manager = None - - def get_voice_manager(self): - if self._voice_manager is None: - self._voice_manager = get_voice_manager(self.bot) - return self._voice_manager - - @staticmethod - async def handle_state_change(member, channel, state_type, is_enabled, log_channel): - """Helper method to handle voice state changes""" - state_messages = { - 'deaf': { - True: f"{member.display_name} jest bity przez ojca", - False: f"{member.display_name} uciek od ojca" - }, - 'mute': { - True: f"{member.display_name} idzie robić jajecznice", - False: f"{member.display_name} zrobił jajecznice" - } - } - - tts_text = state_messages[state_type][is_enabled] - return tts_text, channel - - async def play_tts(self, channel, text): - from cogs.utils.temp import get_temp_dir - - voice_mgr = self.get_voice_manager() - temp_dir = get_temp_dir() - tts_file = os.path.join(temp_dir, f"temp_tts_{os.getpid()}_{asyncio.get_event_loop().time()}.mp3") - tts = gTTS(text=text, lang='pl') - logger.info("saving file") - - loop = asyncio.get_event_loop() - await loop.run_in_executor(None, tts.save, tts_file) - - try: - voice_status = await voice_mgr.get_voice_status(channel.guild) - voice_client = voice_status[0] if voice_status else None - is_connected = voice_status[1] if voice_status else False - is_playing = voice_status[2] if voice_status else False - - if is_connected: - from cogs.voice import is_voice_client_alive - if not is_voice_client_alive(voice_client, channel.guild): - logger.warning("Stale voice client in play_tts, reconnecting") - try: - await voice_client.disconnect() - except Exception: - pass - is_connected = False - - if not is_connected: - voice_client = await voice_mgr.join_channel(channel) - voice_status = await voice_mgr.get_voice_status(channel.guild) - voice_client = voice_status[0] if voice_status else None - is_connected = voice_status[1] if voice_status else False - is_playing = voice_status[2] if voice_status else False - - if not is_connected or voice_client is None: - logger.error("Failed to join voice channel") - return - - volume = get_volume() - logger.info(f"connected: {voice_client}") - - if voice_client: - if is_playing: - logger.info("voice already playing, skipping TTS") - return - - logger.info("preparing to play audio") - audio_source = discord.FFmpegPCMAudio(tts_file) - await voice_mgr.play_source(channel, audio_source, volume=volume) - except Exception as e: - logger.error(f"TTS playback error: {e}") - finally: - if os.path.exists(tts_file): - os.remove(tts_file) - - @commands.slash_command( - name="log_volume" - ) - async def volume(self, ctx: discord.ApplicationContext, volume: int): - from cogs.utils.settings import get_settings - settings = get_settings() - settings.volume = volume - await save_settings() - await ctx.followup.send(f"Volume has been set to: {volume}") - logger.info(f"Volume changed to: {volume}") - - @commands.Cog.listener() - async def on_voice_state_update(self, member, before, after): - log_channel_id = os.getenv("STATUS_CHANNEL_ID") - if not log_channel_id: - logger.warning("STATUS_CHANNEL_ID not set in environment") - return - - log_channel = self.bot.get_channel(int(log_channel_id)) - if log_channel is None: - logger.warning("Log channel not found or not accessible") - return - - current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") - current_ts = datetime.datetime.now().timestamp() - tts_text = None - tts_channel = None - - if member.bot: - return - - user_id = str(member.id) - activity_data = load_activity_data() - - if before.channel is None and after.channel is not None: - is_afk = after.self_mute or after.self_deaf - activity_data[user_id] = { - 'join_time': current_ts, - 'total_active': 0, - 'total_afk': 0, - 'is_afk': is_afk, - 'afk_start': current_ts if is_afk else None, - 'active_start': current_ts if not is_afk else None, - 'channel_name': after.channel.name - } - save_activity_data(activity_data) - - message = f"[{current_time}] {member.name} dołączył na {after.channel.name} " - tts_text = f"{member.display_name} sie zespawnił" - tts_channel = after.channel - await log_channel.send(message) - logger.info(f"User joined voice channel: {message}") - - elif before.channel is not None and after.channel is None: - if user_id in activity_data: - data = activity_data[user_id] - - if data.get('is_afk') and data.get('afk_start'): - afk_duration = current_ts - data['afk_start'] - data['total_afk'] += afk_duration - elif data.get('active_start'): - active_since_start = current_ts - data['active_start'] - data['total_active'] += active_since_start - - active_str = format_duration(data['total_active']) - afk_str = format_duration(data['total_afk']) - - message = ( - f"[{current_time}] {member.name} rozłączył się z {before.channel.name} \n" - f"Aktywny: {active_str} | AFK: {afk_str}" - ) - tts_text = f"{member.display_name} jest chujem" - tts_channel = before.channel - await log_channel.send(message) - logger.info(f"User left voice channel: {message}") - - del activity_data[user_id] - save_activity_data(activity_data) - else: - message = f"[{current_time}] {member.name} rozłączył się z {before.channel.name} " - tts_text = f"{member.display_name} jest chujem" - tts_channel = before.channel - await log_channel.send(message) - logger.info(f"User left voice channel: {message}") - - elif user_id in activity_data: - data = activity_data[user_id] - - if data.get('is_afk') and not (after.self_mute or after.self_deaf): - afk_duration = current_ts - data['afk_start'] - data['total_afk'] += afk_duration - data['afk_start'] = None - data['is_afk'] = False - data['active_start'] = current_ts - save_activity_data(activity_data) - - afk_str = format_duration(afk_duration) - - if after.self_mute: - activity = "odciszył" - else: - activity = "odgłuchnął" - - message = ( f"[{current_time}] {member.name} {activity} się na {after.channel.name} \n" - f"AFK: {afk_str}" ) - await log_channel.send(message) - logger.info(f"User returned from AFK: {message}") - elif not data.get('is_afk') and (after.self_mute or after.self_deaf): - active_since_start = 0 - if data.get('active_start'): - active_since_start = current_ts - data['active_start'] - data['total_active'] += active_since_start - data['afk_start'] = current_ts - data['is_afk'] = True - data['active_start'] = None - save_activity_data(activity_data) - - if after.self_mute: - activity = "wyciszył" - else: - activity = "ogłuchnął" - - active_str = format_duration(active_since_start) - message = ( f"[{current_time}] {member.name} {activity} się na {after.channel.name} \n" - f"Aktywny: {active_str}" ) - await log_channel.send(message) - logger.info(f"User went AFK: {message}") - - if before.self_deaf != after.self_deaf: - tts_text, tts_channel = await self.handle_state_change( - member, after.channel, 'deaf', after.self_deaf, log_channel - ) - if tts_text and tts_channel: - await self.play_tts(tts_channel, tts_text) - return - - if before.self_mute != after.self_mute: - tts_text, tts_channel = await self.handle_state_change( - member, after.channel, 'mute', after.self_mute, log_channel - ) - - if tts_text and tts_channel: - await self.play_tts(tts_channel, tts_text) - - -def setup(bot): - bot.add_cog(VcLogs(bot)) -- cgit v1.2.3