diff options
Diffstat (limited to 'cogs')
| -rw-r--r-- | cogs/vclogs.py | 126 |
1 files changed, 116 insertions, 10 deletions
diff --git a/cogs/vclogs.py b/cogs/vclogs.py index 9ed7134..0589364 100644 --- a/cogs/vclogs.py +++ b/cogs/vclogs.py | |||
| @@ -16,6 +16,30 @@ from cogs.voice import get_voice_manager | |||
| 16 | 16 | ||
| 17 | logger = logging.getLogger(__name__) | 17 | logger = logging.getLogger(__name__) |
| 18 | 18 | ||
| 19 | ACTIVITY_FILE = 'temp/voice_activity.json' | ||
| 20 | |||
| 21 | |||
| 22 | def load_activity_data(): | ||
| 23 | if os.path.exists(ACTIVITY_FILE): | ||
| 24 | with open(ACTIVITY_FILE, 'r') as f: | ||
| 25 | return json.load(f) | ||
| 26 | return {} | ||
| 27 | |||
| 28 | |||
| 29 | def save_activity_data(data): | ||
| 30 | with open(ACTIVITY_FILE, 'w') as f: | ||
| 31 | json.dump(data, f, indent=4) | ||
| 32 | |||
| 33 | |||
| 34 | def format_duration(seconds): | ||
| 35 | hours, remainder = divmod(int(seconds), 3600) | ||
| 36 | minutes, seconds = divmod(remainder, 60) | ||
| 37 | if hours > 0: | ||
| 38 | return f"{hours}h {minutes}m {seconds}s" | ||
| 39 | elif minutes > 0: | ||
| 40 | return f"{minutes}m {seconds}s" | ||
| 41 | return f"{seconds}s" | ||
| 42 | |||
| 19 | 43 | ||
| 20 | class VcLogs(commands.Cog): | 44 | class VcLogs(commands.Cog): |
| 21 | def __init__(self, bot): | 45 | def __init__(self, bot): |
| @@ -30,7 +54,7 @@ class VcLogs(commands.Cog): | |||
| 30 | settings_file = 'settings.json' | 54 | settings_file = 'settings.json' |
| 31 | 55 | ||
| 32 | @staticmethod | 56 | @staticmethod |
| 33 | async def handle_state_change(member, channel, state_type, is_enabled, current_time, log_channel): | 57 | async def handle_state_change(member, channel, state_type, is_enabled, current_time, log_channel, activity_suffix=None): |
| 34 | """Helper method to handle voice state changes""" | 58 | """Helper method to handle voice state changes""" |
| 35 | state_messages = { | 59 | state_messages = { |
| 36 | 'deaf': { | 60 | 'deaf': { |
| @@ -56,6 +80,8 @@ class VcLogs(commands.Cog): | |||
| 56 | } | 80 | } |
| 57 | 81 | ||
| 58 | message, tts_text = state_messages[state_type][is_enabled] | 82 | message, tts_text = state_messages[state_type][is_enabled] |
| 83 | if activity_suffix: | ||
| 84 | message = f"{message}\n{activity_suffix}" | ||
| 59 | await log_channel.send(message) | 85 | await log_channel.send(message) |
| 60 | logger.info(f"Voice state change: {message}") | 86 | logger.info(f"Voice state change: {message}") |
| 61 | return tts_text, channel | 87 | return tts_text, channel |
| @@ -109,37 +135,117 @@ class VcLogs(commands.Cog): | |||
| 109 | async def on_voice_state_update(self, member, before, after): | 135 | async def on_voice_state_update(self, member, before, after): |
| 110 | log_channel = self.bot.get_channel(1213843195457183885) | 136 | log_channel = self.bot.get_channel(1213843195457183885) |
| 111 | current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") | 137 | current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
| 138 | current_ts = datetime.datetime.now().timestamp() | ||
| 112 | tts_text = None | 139 | tts_text = None |
| 113 | tts_channel = None | 140 | tts_channel = None |
| 114 | 141 | ||
| 115 | # Ignore if the user is a bot | ||
| 116 | if member.bot: | 142 | if member.bot: |
| 117 | return | 143 | return |
| 118 | 144 | ||
| 145 | user_id = str(member.id) | ||
| 146 | activity_data = load_activity_data() | ||
| 147 | |||
| 119 | if before.channel is None and after.channel is not None: | 148 | if before.channel is None and after.channel is not None: |
| 149 | is_afk = after.self_mute or after.self_deaf | ||
| 150 | activity_data[user_id] = { | ||
| 151 | 'join_time': current_ts, | ||
| 152 | 'total_active': 0, | ||
| 153 | 'total_afk': 0, | ||
| 154 | 'is_afk': is_afk, | ||
| 155 | 'afk_start': current_ts if is_afk else None, | ||
| 156 | 'active_start': current_ts if not is_afk else None, | ||
| 157 | 'channel_name': after.channel.name | ||
| 158 | } | ||
| 159 | save_activity_data(activity_data) | ||
| 160 | |||
| 120 | message = f"[{current_time}] {member.name} dołączył na {after.channel.name}" | 161 | message = f"[{current_time}] {member.name} dołączył na {after.channel.name}" |
| 121 | tts_text = f"{member.display_name} sie zespawnił" | 162 | tts_text = f"{member.display_name} sie zespawnił" |
| 122 | tts_channel = after.channel | 163 | tts_channel = after.channel |
| 123 | await log_channel.send(message) | 164 | await log_channel.send(message) |
| 124 | logger.info(f"User joined voice channel: {message}") | 165 | logger.info(f"User joined voice channel: {message}") |
| 166 | |||
| 125 | elif before.channel is not None and after.channel is None: | 167 | elif before.channel is not None and after.channel is None: |
| 126 | message = f"[{current_time}] {member.name} rozłączył się z {before.channel.name}" | 168 | if user_id in activity_data: |
| 127 | tts_text = f"{member.display_name} jest chujem" | 169 | data = activity_data[user_id] |
| 128 | tts_channel = before.channel | 170 | |
| 129 | await log_channel.send(message) | 171 | if data.get('is_afk') and data.get('afk_start'): |
| 130 | logger.info(f"User left voice channel: {message}") | 172 | afk_duration = current_ts - data['afk_start'] |
| 173 | data['total_afk'] += afk_duration | ||
| 174 | elif data.get('active_start'): | ||
| 175 | active_since_start = current_ts - data['active_start'] | ||
| 176 | data['total_active'] += active_since_start | ||
| 177 | |||
| 178 | active_str = format_duration(data['total_active']) | ||
| 179 | afk_str = format_duration(data['total_afk']) | ||
| 180 | |||
| 181 | message = ( | ||
| 182 | f"[{current_time}] {member.name} rozłączył się z {before.channel.name}\n" | ||
| 183 | f" Aktywny: {active_str} | AFK: {afk_str}" | ||
| 184 | ) | ||
| 185 | tts_text = f"{member.display_name} jest chujem" | ||
| 186 | tts_channel = before.channel | ||
| 187 | await log_channel.send(message) | ||
| 188 | logger.info(f"User left voice channel: {message}") | ||
| 189 | |||
| 190 | del activity_data[user_id] | ||
| 191 | save_activity_data(activity_data) | ||
| 192 | else: | ||
| 193 | message = f"[{current_time}] {member.name} rozłączył się z {before.channel.name}" | ||
| 194 | tts_text = f"{member.display_name} jest chujem" | ||
| 195 | tts_channel = before.channel | ||
| 196 | await log_channel.send(message) | ||
| 197 | logger.info(f"User left voice channel: {message}") | ||
| 198 | |||
| 199 | elif user_id in activity_data: | ||
| 200 | data = activity_data[user_id] | ||
| 201 | |||
| 202 | if data.get('is_afk') and not (after.self_mute or after.self_deaf): | ||
| 203 | afk_duration = current_ts - data['afk_start'] | ||
| 204 | data['total_afk'] += afk_duration | ||
| 205 | data['afk_start'] = None | ||
| 206 | data['is_afk'] = False | ||
| 207 | data['active_start'] = current_ts | ||
| 208 | save_activity_data(activity_data) | ||
| 209 | elif not data.get('is_afk') and (after.self_mute or after.self_deaf): | ||
| 210 | if data.get('active_start'): | ||
| 211 | active_since_start = current_ts - data['active_start'] | ||
| 212 | data['total_active'] += active_since_start | ||
| 213 | data['afk_start'] = current_ts | ||
| 214 | data['is_afk'] = True | ||
| 215 | data['active_start'] = None | ||
| 216 | save_activity_data(activity_data) | ||
| 131 | 217 | ||
| 132 | if before.self_deaf != after.self_deaf: | 218 | if before.self_deaf != after.self_deaf: |
| 219 | activity_suffix = None | ||
| 220 | if user_id in activity_data: | ||
| 221 | data = activity_data[user_id] | ||
| 222 | if after.self_deaf: | ||
| 223 | active_str = format_duration(data['total_active']) | ||
| 224 | activity_suffix = f" Aktywny przed AFK: {active_str}" | ||
| 225 | else: | ||
| 226 | active_str = format_duration(data['total_active']) | ||
| 227 | afk_str = format_duration(data['total_afk']) | ||
| 228 | activity_suffix = f" Był AFK: {afk_str} | Łączny aktywny: {active_str}" | ||
| 133 | tts_text, tts_channel = await self.handle_state_change( | 229 | tts_text, tts_channel = await self.handle_state_change( |
| 134 | member, after.channel, 'deaf', after.self_deaf, current_time, log_channel | 230 | member, after.channel, 'deaf', after.self_deaf, current_time, log_channel, activity_suffix |
| 135 | ) | 231 | ) |
| 136 | if tts_text and tts_channel: | 232 | if tts_text and tts_channel: |
| 137 | await self.play_tts(tts_channel, tts_text) | 233 | await self.play_tts(tts_channel, tts_text) |
| 138 | return | 234 | return |
| 139 | 235 | ||
| 140 | if before.self_mute != after.self_mute: | 236 | if before.self_mute != after.self_mute: |
| 237 | activity_suffix = None | ||
| 238 | if user_id in activity_data: | ||
| 239 | data = activity_data[user_id] | ||
| 240 | if after.self_mute: | ||
| 241 | active_str = format_duration(data['total_active']) | ||
| 242 | activity_suffix = f" Aktywny przed AFK: {active_str}" | ||
| 243 | else: | ||
| 244 | active_str = format_duration(data['total_active']) | ||
| 245 | afk_str = format_duration(data['total_afk']) | ||
| 246 | activity_suffix = f" Był AFK: {afk_str} | Łączny aktywny: {active_str}" | ||
| 141 | tts_text, tts_channel = await self.handle_state_change( | 247 | tts_text, tts_channel = await self.handle_state_change( |
| 142 | member, after.channel, 'mute', after.self_mute, current_time, log_channel | 248 | member, after.channel, 'mute', after.self_mute, current_time, log_channel, activity_suffix |
| 143 | ) | 249 | ) |
| 144 | 250 | ||
| 145 | if tts_text and tts_channel: | 251 | if tts_text and tts_channel: |
| @@ -147,4 +253,4 @@ class VcLogs(commands.Cog): | |||
| 147 | 253 | ||
| 148 | 254 | ||
| 149 | def setup(bot): | 255 | def setup(bot): |
| 150 | bot.add_cog(VcLogs(bot)) \ No newline at end of file | 256 | bot.add_cog(VcLogs(bot)) |
