import discord from discord.ext import commands from discord import app_commands from datetime import datetime, timezone import time from database import Database # Premium Renkler CYBER_BLUE = discord.Color.from_rgb(52, 152, 219) CYBER_DARK = discord.Color.from_rgb(44, 62, 80) CYBER_GREEN = discord.Color.from_rgb(46, 204, 113) class Stats(commands.Cog): def __init__(self, bot): self.bot = bot # Ses kanalına katılan üyelerin giriş zamanları: {member_id: timestamp} self.voice_join_times = {} def _get_today_str(self): return datetime.now().date().isoformat() def _format_duration(self, seconds: int) -> str: if seconds <= 0: return "0 saniye" hours = seconds // 3600 minutes = (seconds % 3600) // 60 secs = seconds % 60 parts = [] if hours > 0: parts.append(f"{hours} saat") if minutes > 0: parts.append(f"{minutes} dakika") if secs > 0 or not parts: parts.append(f"{secs} saniye") return " ".join(parts) def _generate_bar(self, value, max_val, size=10) -> str: if max_val <= 0: return "░" * size filled = int((value / max_val) * size) filled = min(filled, size) return "█" * filled + "░" * (size - filled) # --- SOhBET AKTİFLİĞİ SAYICI --- @commands.Cog.listener() async def on_message(self, message: discord.Message): if message.author.bot or not message.guild: return if not await Database.modul_aktif_mi(message.guild.id, "Stats"): return today = self._get_today_str() await Database.aktiflik_mesaj_arttir(message.guild.id, message.author.id, today) # --- SES AKTİFLİĞİ TAKİPÇİSİ --- @commands.Cog.listener() async def on_voice_state_update(self, member: discord.Member, before: discord.VoiceState, after: discord.VoiceState): if member.bot or not member.guild: return if not await Database.modul_aktif_mi(member.guild.id, "Stats"): return user_id = member.id guild_id = member.guild.id today = self._get_today_str() now = time.time() # Durum 1: Ses kanalına giriş yaptı (Eski kanalı yoktu, yenisi var) if before.channel is None and after.channel is not None: self.voice_join_times[user_id] = now # Durum 2: Ses kanalından çıkış yaptı (Eski kanalı vardı, yenisi yok) elif before.channel is not None and after.channel is None: join_time = self.voice_join_times.pop(user_id, None) if join_time: duration = int(now - join_time) if duration > 0: await Database.aktiflik_ses_ekle(guild_id, user_id, today, duration) # Durum 3: Ses kanalı değiştirdi (Her ikisi de var ama farklı kanallar) elif before.channel is not None and after.channel is not None and before.channel.id != after.channel.id: join_time = self.voice_join_times.get(user_id, None) if join_time: duration = int(now - join_time) if duration > 0: await Database.aktiflik_ses_ekle(guild_id, user_id, today, duration) # Zamanı sıfırla yeni kanalda kalmaya devam etsin self.voice_join_times[user_id] = now # --- KOMUTLAR --- @commands.hybrid_command(name="istatistik", description="Kendi aktiflik istatistiklerinizi veya başka bir üyeninkini görüntüler.") @app_commands.describe(uye="İstatistiklerine bakılacak üye") async def istatistik(self, ctx: commands.Context, uye: discord.Member = None): if ctx.interaction: await ctx.defer() target = uye or ctx.author stats = await Database.aktiflik_getir(ctx.guild.id, target.id) # Son 7 günün mesaj verileri mesaj_detay = "" toplam_7_gun_mesaj = 0 max_7_gun_mesaj = 0 for r in stats["son_7_gun_mesaj"]: toplam_7_gun_mesaj += r["mesaj_sayisi"] if r["mesaj_sayisi"] > max_7_gun_mesaj: max_7_gun_mesaj = r["mesaj_sayisi"] # Tersten sıralayarak eskiden yeniye doğru günleri listele for r in reversed(stats["son_7_gun_mesaj"]): bar = self._generate_bar(r["mesaj_sayisi"], max_7_gun_mesaj) mesaj_detay += f"`{r['gun_tarih']}` {bar} `{r['mesaj_sayisi']} mesaj`\n" # Son 7 günün ses verileri ses_detay = "" toplam_7_gun_ses = 0 max_7_gun_ses = 0 for r in stats["son_7_gun_ses"]: toplam_7_gun_ses += r["ses_suresi_sn"] if r["ses_suresi_sn"] > max_7_gun_ses: max_7_gun_ses = r["ses_suresi_sn"] for r in reversed(stats["son_7_gun_ses"]): bar = self._generate_bar(r["ses_suresi_sn"], max_7_gun_ses) ses_detay += f"`{r['gun_tarih']}` {bar} `{self._format_duration(r['ses_suresi_sn'])}`\n" embed = discord.Embed( title=f"📊 Aktiflik İstatistikleri - {target.display_name}", color=CYBER_BLUE, timestamp=datetime.now() ) embed.set_thumbnail(url=target.display_avatar.url) # Özet Bölümü embed.add_field(name="✉️ Toplam Mesaj", value=f"`{stats['toplam_mesaj']}` adet", inline=True) embed.add_field(name="🔊 Toplam Ses Süresi", value=f"`{self._format_duration(stats['toplam_ses'])}`", inline=True) # Detaylar if mesaj_detay: embed.add_field(name="📅 Son 7 Gün Mesaj İstatistiği", value=mesaj_detay, inline=False) else: embed.add_field(name="📅 Son 7 Gün Mesaj İstatistiği", value="*Son 7 günde kaydedilmiş mesaj yok.*", inline=False) if ses_detay: embed.add_field(name="⏱️ Son 7 Gün Ses İstatistiği", value=ses_detay, inline=False) else: embed.add_field(name="⏱️ Son 7 Gün Ses İstatistiği", value="*Son 7 günde kaydedilmiş ses aktifliği yok.*", inline=False) await ctx.send(embed=embed) @commands.hybrid_command(name="top-aktiflik", description="Sunucudaki aktiflik sıralamasını (mesaj ve ses) gösterir.") async def top_aktiflik(self, ctx: commands.Context): if ctx.interaction: await ctx.defer() top_mesaj = await Database.aktiflik_siralamasi_mesaj(ctx.guild.id, 10) top_ses = await Database.aktiflik_siralamasi_ses(ctx.guild.id, 10) mesaj_list = [] for i, row in enumerate(top_mesaj, 1): member = ctx.guild.get_member(row['user_id']) name = member.mention if member else f"ID: {row['user_id']}" mesaj_list.append(f"**{i}.** {name} — `{row['toplam']} mesaj`") ses_list = [] for i, row in enumerate(top_ses, 1): member = ctx.guild.get_member(row['user_id']) name = member.mention if member else f"ID: {row['user_id']}" ses_list.append(f"**{i}.** {name} — `{self._format_duration(row['toplam'])}`") embed = discord.Embed( title=f"🏆 Sunucu Aktiflik Sıralaması", color=CYBER_GREEN, timestamp=datetime.now() ) embed.add_field(name="✉️ En Çok Mesaj Atanlar", value="\n".join(mesaj_list) if mesaj_list else "*Veri yok.*", inline=False) embed.add_field(name="🔊 En Çok Seste Kalanlar", value="\n".join(ses_list) if ses_list else "*Veri yok.*", inline=False) await ctx.send(embed=embed) async def setup(bot): await bot.add_cog(Stats(bot))