Hilmany / cogs /stats.py
HilmanBey's picture
Upload 64 files
cbb05ec verified
Raw
History Blame Contribute Delete
7.76 kB
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))