diff options
Diffstat (limited to '')
| -rw-r--r-- | cogs/ai.py | 20 | ||||
| -rw-r--r-- | cogs/compression.py | 25 | ||||
| -rw-r--r-- | cogs/downloader.py | 32 | ||||
| -rw-r--r-- | cogs/math.py | 16 | ||||
| -rw-r--r-- | cogs/music/join.py | 5 | ||||
| -rw-r--r-- | cogs/music/leave.py | 5 | ||||
| -rw-r--r-- | cogs/music/loop.py | 4 | ||||
| -rw-r--r-- | cogs/music/play.py | 55 | ||||
| -rw-r--r-- | cogs/music/play_compressed.py | 15 | ||||
| -rw-r--r-- | cogs/music/queue.py | 6 | ||||
| -rw-r--r-- | cogs/music/skip.py | 29 | ||||
| -rw-r--r-- | cogs/ping_commands.py | 60 | ||||
| -rw-r--r-- | cogs/tts.py | 19 | ||||
| -rw-r--r-- | cogs/vclogs.py (renamed from cogs/vc_logs.py) | 86 |
14 files changed, 182 insertions, 195 deletions
| @@ -1,7 +1,9 @@ | |||
| 1 | import os | ||
| 2 | |||
| 1 | import discord | 3 | import discord |
| 2 | from discord.ext import commands | ||
| 3 | import google.generativeai as genai | 4 | import google.generativeai as genai |
| 4 | import os | 5 | from discord.ext import commands |
| 6 | |||
| 5 | 7 | ||
| 6 | class AI(commands.Cog): | 8 | class AI(commands.Cog): |
| 7 | def __init__(self, bot): | 9 | def __init__(self, bot): |
| @@ -12,22 +14,22 @@ class AI(commands.Cog): | |||
| 12 | description="SEENATOR", | 14 | description="SEENATOR", |
| 13 | ) | 15 | ) |
| 14 | async def senator( | 16 | async def senator( |
| 15 | self, | 17 | self, |
| 16 | ctx: discord.ApplicationContext, | 18 | ctx: discord.ApplicationContext, |
| 17 | text = discord.Option(str, "message", required=True) | 19 | text=discord.Option(str, "message", required=True) |
| 18 | ): | 20 | ): |
| 19 | ''' | 21 | """ |
| 20 | OOWA this so impressive gwachan >w< | 22 | OOWA this so impressive gwachan >w< |
| 21 | I can't believe you made this you are so good gwachan :3 | 23 | I can't believe you made this you are so good gwachan :3 |
| 22 | ''' | 24 | """ |
| 23 | await ctx.defer() | 25 | await ctx.defer() |
| 24 | genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) | 26 | genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) |
| 25 | model = genai.GenerativeModel("gemini-1.5-flash") | 27 | model = genai.GenerativeModel("gemini-1.5-flash") |
| 26 | response = model.generate_content( | 28 | response = model.generate_content( |
| 27 | "You are Senator Steaven Sperma Armstrong from Metal Gear Rising Vengeance. Respond in plain text, no ** or "". If the message is in Polish, respond in Polish. Respond in 100 words. Respond accordingly to this message: "+text, | 29 | "You are Senator Steaven Sperma Armstrong from Metal Gear Rising Vengeance. Respond in plain text, no ** or "". If the message is in Polish, respond in Polish. Respond in 100 words. Respond accordingly to this message: " + text, |
| 28 | ) | 30 | ) |
| 29 | await ctx.respond(response.text) | 31 | await ctx.respond(response.text) |
| 30 | 32 | ||
| 33 | |||
| 31 | def setup(bot): | 34 | def setup(bot): |
| 32 | bot.add_cog(AI(bot)) | 35 | bot.add_cog(AI(bot)) |
| 33 | \ No newline at end of file | ||
diff --git a/cogs/compression.py b/cogs/compression.py index dfd96ae..ddfa545 100644 --- a/cogs/compression.py +++ b/cogs/compression.py | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | import discord | ||
| 2 | from discord.ext import commands | ||
| 3 | import asyncio | ||
| 4 | import mimetypes | 1 | import mimetypes |
| 5 | import os | 2 | import os |
| 6 | import subprocess | 3 | import subprocess |
| 7 | import tempfile | 4 | |
| 5 | import discord | ||
| 6 | from discord.ext import commands | ||
| 7 | |||
| 8 | 8 | ||
| 9 | def filetype(filename): | 9 | def filetype(filename): |
| 10 | mime_type, _ = mimetypes.guess_type(filename) | 10 | mime_type, _ = mimetypes.guess_type(filename) |
| @@ -17,10 +17,11 @@ def filetype(filename): | |||
| 17 | return "Image" | 17 | return "Image" |
| 18 | return "Unknown" | 18 | return "Unknown" |
| 19 | 19 | ||
| 20 | |||
| 20 | class Compression(commands.Cog): | 21 | class Compression(commands.Cog): |
| 21 | def __init__(self, bot): | 22 | def __init__(self, bot): |
| 22 | self.bot = bot | 23 | self.bot = bot |
| 23 | 24 | ||
| 24 | @commands.slash_command( | 25 | @commands.slash_command( |
| 25 | name="kompresja", | 26 | name="kompresja", |
| 26 | description="skompresuj wideło albo dźwienk :)", | 27 | description="skompresuj wideło albo dźwienk :)", |
| @@ -33,14 +34,14 @@ class Compression(commands.Cog): | |||
| 33 | ) | 34 | ) |
| 34 | async def compression(self, ctx, plik): | 35 | async def compression(self, ctx, plik): |
| 35 | await ctx.defer() | 36 | await ctx.defer() |
| 36 | # Save files to temp directory inside the bot's root directory | 37 | # Save files to the temp directory inside the bot's root directory |
| 37 | bot_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | 38 | bot_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| 38 | temp_dir = os.path.join(bot_dir, "temp") | 39 | temp_dir = os.path.join(bot_dir, "temp") |
| 39 | if not os.path.exists(temp_dir): | 40 | if not os.path.exists(temp_dir): |
| 40 | os.makedirs(temp_dir) | 41 | os.makedirs(temp_dir) |
| 41 | file_path = os.path.join(temp_dir, plik.filename) | 42 | file_path = os.path.join(temp_dir, plik.filename) |
| 42 | await plik.save(file_path) | 43 | await plik.save(file_path) |
| 43 | 44 | ||
| 44 | input_path = file_path | 45 | input_path = file_path |
| 45 | output_path = os.path.join(temp_dir, f"better_{plik.filename}") | 46 | output_path = os.path.join(temp_dir, f"better_{plik.filename}") |
| 46 | file_type = filetype(file_path) | 47 | file_type = filetype(file_path) |
| @@ -51,7 +52,7 @@ class Compression(commands.Cog): | |||
| 51 | ffmpeg_command = f"ffmpeg -i {input_path} -ar 8000 -ac 1 -b:a 16k -acodec libmp3lame -q:a 9 {output_path}" | 52 | ffmpeg_command = f"ffmpeg -i {input_path} -ar 8000 -ac 1 -b:a 16k -acodec libmp3lame -q:a 9 {output_path}" |
| 52 | elif file_type == "Image": | 53 | elif file_type == "Image": |
| 53 | # Use ImageMagick's magick to heavily compress image (JPEG/PNG/GIF) | 54 | # Use ImageMagick's magick to heavily compress image (JPEG/PNG/GIF) |
| 54 | # For JPEG: quality 5, strip metadata, resize to 30% of original size | 55 | # For JPEG: quality 5, strip metadata, resize to 30% of the original size |
| 55 | # For PNG: magick to JPEG, then compress | 56 | # For PNG: magick to JPEG, then compress |
| 56 | # For GIF: optimize and reduce colors | 57 | # For GIF: optimize and reduce colors |
| 57 | ext = os.path.splitext(input_path)[1].lower() | 58 | ext = os.path.splitext(input_path)[1].lower() |
| @@ -68,10 +69,10 @@ class Compression(commands.Cog): | |||
| 68 | else: | 69 | else: |
| 69 | await ctx.respond("Plik jest nieobsługiwany", ephemeral=True) | 70 | await ctx.respond("Plik jest nieobsługiwany", ephemeral=True) |
| 70 | return | 71 | return |
| 71 | 72 | ||
| 72 | try: | 73 | try: |
| 73 | subprocess.run(ffmpeg_command, check=True, shell=True) | 74 | subprocess.run(ffmpeg_command, check=True, shell=True) |
| 74 | # Upload compressed file | 75 | # Upload the compressed file |
| 75 | await ctx.respond(file=discord.File(output_path)) | 76 | await ctx.respond(file=discord.File(output_path)) |
| 76 | # Delete compressed file | 77 | # Delete compressed file |
| 77 | os.remove(input_path) | 78 | os.remove(input_path) |
| @@ -85,4 +86,4 @@ class Compression(commands.Cog): | |||
| 85 | 86 | ||
| 86 | 87 | ||
| 87 | def setup(bot): | 88 | def setup(bot): |
| 88 | bot.add_cog(Compression(bot)) \ No newline at end of file | 89 | bot.add_cog(Compression(bot)) |
diff --git a/cogs/downloader.py b/cogs/downloader.py index 7f48e57..c35373f 100644 --- a/cogs/downloader.py +++ b/cogs/downloader.py | |||
| @@ -1,12 +1,13 @@ | |||
| 1 | import base64 | 1 | import base64 |
| 2 | import os | 2 | import os |
| 3 | import os.path | ||
| 4 | import tempfile | ||
| 5 | |||
| 3 | import discord | 6 | import discord |
| 4 | from discord.ext import commands | ||
| 5 | import requests | 7 | import requests |
| 6 | import yt_dlp | 8 | import yt_dlp |
| 9 | from discord.ext import commands | ||
| 7 | from dotenv import load_dotenv | 10 | from dotenv import load_dotenv |
| 8 | import tempfile | ||
| 9 | import os.path | ||
| 10 | 11 | ||
| 11 | # Load environment variables | 12 | # Load environment variables |
| 12 | load_dotenv() | 13 | load_dotenv() |
| @@ -34,9 +35,9 @@ class Downloader(commands.Cog): | |||
| 34 | description="download video from internet", | 35 | description="download video from internet", |
| 35 | ) | 36 | ) |
| 36 | async def download( | 37 | async def download( |
| 37 | self, | 38 | self, |
| 38 | ctx: discord.ApplicationContext, | 39 | ctx: discord.ApplicationContext, |
| 39 | url: discord.Option(str, "url", required=True) | 40 | url: discord.Option(str, "url", required=True) |
| 40 | ): | 41 | ): |
| 41 | await ctx.defer() | 42 | await ctx.defer() |
| 42 | try: | 43 | try: |
| @@ -52,7 +53,7 @@ class Downloader(commands.Cog): | |||
| 52 | with yt_dlp.YoutubeDL(ydl_opts) as ydl: | 53 | with yt_dlp.YoutubeDL(ydl_opts) as ydl: |
| 53 | info = ydl.extract_info(url, download=True) | 54 | info = ydl.extract_info(url, download=True) |
| 54 | actual_filename = ydl.prepare_filename(info) | 55 | actual_filename = ydl.prepare_filename(info) |
| 55 | 56 | ||
| 56 | await ctx.followup.send("Video downloaded successfully, Uploading to pixeldrain...") | 57 | await ctx.followup.send("Video downloaded successfully, Uploading to pixeldrain...") |
| 57 | # upload to pixeldrain | 58 | # upload to pixeldrain |
| 58 | try: | 59 | try: |
| @@ -61,37 +62,40 @@ class Downloader(commands.Cog): | |||
| 61 | response = requests.post( | 62 | response = requests.post( |
| 62 | self.pixeldrain_url, | 63 | self.pixeldrain_url, |
| 63 | files=files, | 64 | files=files, |
| 64 | headers={"Authorization": f"Basic {base64.b64encode((':' + PIXELDRAIN_API_KEY).encode()).decode()}"} | 65 | headers={ |
| 66 | "Authorization": f"Basic {base64.b64encode((':' + PIXELDRAIN_API_KEY).encode()).decode()}"} | ||
| 65 | ) | 67 | ) |
| 66 | 68 | ||
| 67 | try: | 69 | try: |
| 68 | response_data = response.json() | 70 | response_data = response.json() |
| 69 | print("Pixeldrain response:", response_data) # Debug log | 71 | print("Pixeldrain response:", response_data) # Debug log |
| 70 | 72 | ||
| 71 | if response.status_code == 201: # 201 means successful upload | 73 | if response.status_code == 201: # 201 means successful upload |
| 72 | file_id = response_data.get('id') | 74 | file_id = response_data.get('id') |
| 73 | if file_id: | 75 | if file_id: |
| 74 | file_link = f"https://pixeldrain.com/u/{file_id}" | 76 | file_link = f"https://pixeldrain.com/u/{file_id}" |
| 75 | await ctx.followup.send(f"oto twoje videło\n {file_link}") | 77 | await ctx.followup.send(f"oto twoje videło\n {file_link}") |
| 76 | else: | 78 | else: |
| 77 | await ctx.followup.send(f"⚠️ Upload successful but no file ID returned. Response: {response_data}") | 79 | await ctx.followup.send( |
| 80 | f"⚠️ Upload successful but no file ID returned. Response: {response_data}") | ||
| 78 | else: | 81 | else: |
| 79 | error_msg = response_data.get('error', 'Unknown error') | 82 | error_msg = response_data.get('error', 'Unknown error') |
| 80 | if response.status_code == 401: | 83 | if response.status_code == 401: |
| 81 | error_msg = "Invalid API key. Please check your PIXELDRAIN_API_KEY in .env file." | 84 | error_msg = "Invalid API key. Please check your PIXELDRAIN_API_KEY in .env file." |
| 82 | await ctx.followup.send(f"❌ Upload failed (Status {response.status_code}): {error_msg}") | 85 | await ctx.followup.send(f"❌ Upload failed (Status {response.status_code}): {error_msg}") |
| 83 | except ValueError as e: | 86 | except ValueError as e: |
| 84 | # If response is not JSON | 87 | # If the response is not JSON |
| 85 | error_msg = f"Failed to parse server response: {str(e)}" | 88 | error_msg = f"Failed to parse server response: {str(e)}" |
| 86 | if response.text: | 89 | if response.text: |
| 87 | error_msg += f"\nResponse: {response.text[:200]}" | 90 | error_msg += f"\nResponse: {response.text[:200]}" |
| 88 | await ctx.followup.send(f"❌ {error_msg}") | 91 | await ctx.followup.send(f"❌ {error_msg}") |
| 89 | except Exception as e: | 92 | except Exception as e: |
| 90 | await ctx.followup.send(f"Error: {str(e)}") | 93 | await ctx.followup.send(f"Error: {str(e)}") |
| 91 | # No need for explicit cleanup as tempfile.TemporaryDirectory handles it automatically | 94 | # No need for explicit cleanup as a tempfile.TemporaryDirectory handles it automatically |
| 92 | 95 | ||
| 93 | except Exception as e: | 96 | except Exception as e: |
| 94 | await ctx.followup.send(f"Error: {str(e)}") | 97 | await ctx.followup.send(f"Error: {str(e)}") |
| 95 | 98 | ||
| 99 | |||
| 96 | def setup(bot): | 100 | def setup(bot): |
| 97 | bot.add_cog(Downloader(bot)) \ No newline at end of file | 101 | bot.add_cog(Downloader(bot)) |
diff --git a/cogs/math.py b/cogs/math.py index df2be4a..53340f2 100644 --- a/cogs/math.py +++ b/cogs/math.py | |||
| @@ -1,23 +1,25 @@ | |||
| 1 | from discord.ext import commands | ||
| 2 | import discord | ||
| 3 | from discord import (ApplicationContext) | ||
| 4 | import subprocess | 1 | import subprocess |
| 5 | 2 | ||
| 3 | from discord import (ApplicationContext) | ||
| 4 | from discord.ext import commands | ||
| 5 | |||
| 6 | |||
| 6 | class Math(commands.Cog): | 7 | class Math(commands.Cog): |
| 7 | def __init__(self, bot): | 8 | def __init__(self, bot): |
| 8 | self.bot = bot | 9 | self.bot = bot |
| 9 | 10 | ||
| 10 | @commands.slash_command( | 11 | @commands.slash_command( |
| 11 | name="math", | 12 | name="math", |
| 12 | description="wrug szyskih matfisuf" | 13 | description="wrug szyskih matfisuf" |
| 13 | ) | 14 | ) |
| 14 | async def math(self, ctx:ApplicationContext, equation:str): | 15 | async def math(self, ctx: ApplicationContext, equation: str): |
| 15 | try: | 16 | try: |
| 16 | math=subprocess.check_output(f"qalc -e {equation}", shell=True) | 17 | math = subprocess.check_output(f"qalc -e {equation}", shell=True) |
| 17 | await ctx.respond(f"{equation} = {math.decode('utf-8').strip()}") | 18 | await ctx.respond(f"{equation} = {math.decode('utf-8').strip()}") |
| 18 | except Exception as e: | 19 | except Exception as e: |
| 19 | await ctx.respond(e, ephemeral=True) | 20 | await ctx.respond(e, ephemeral=True) |
| 20 | print(e) | 21 | print(e) |
| 21 | 22 | ||
| 23 | |||
| 22 | def setup(bot): | 24 | def setup(bot): |
| 23 | bot.add_cog(Math(bot)) \ No newline at end of file | 25 | bot.add_cog(Math(bot)) |
diff --git a/cogs/music/join.py b/cogs/music/join.py index 91a0b18..a613e81 100644 --- a/cogs/music/join.py +++ b/cogs/music/join.py | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | import discord | ||
| 2 | from discord.ext import commands | 1 | from discord.ext import commands |
| 3 | 2 | ||
| 3 | |||
| 4 | class Join(commands.Cog): | 4 | class Join(commands.Cog): |
| 5 | def __init__(self, bot): | 5 | def __init__(self, bot): |
| 6 | self.bot = bot | 6 | self.bot = bot |
| @@ -9,5 +9,6 @@ class Join(commands.Cog): | |||
| 9 | async def join(self, ctx): | 9 | async def join(self, ctx): |
| 10 | await ctx.voice_client.connect() | 10 | await ctx.voice_client.connect() |
| 11 | 11 | ||
| 12 | |||
| 12 | def setup(bot): | 13 | def setup(bot): |
| 13 | bot.add_cog(Join(bot)) \ No newline at end of file | 14 | bot.add_cog(Join(bot)) |
diff --git a/cogs/music/leave.py b/cogs/music/leave.py index 0be2068..7be3b60 100644 --- a/cogs/music/leave.py +++ b/cogs/music/leave.py | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | import discord | ||
| 2 | from discord.ext import commands | 1 | from discord.ext import commands |
| 3 | 2 | ||
| 3 | |||
| 4 | class Leave(commands.Cog): | 4 | class Leave(commands.Cog): |
| 5 | def __init__(self, bot): | 5 | def __init__(self, bot): |
| 6 | self.bot = bot | 6 | self.bot = bot |
| @@ -9,5 +9,6 @@ class Leave(commands.Cog): | |||
| 9 | async def kick(self, ctx): | 9 | async def kick(self, ctx): |
| 10 | await ctx.voice_client.disconnect() | 10 | await ctx.voice_client.disconnect() |
| 11 | 11 | ||
| 12 | |||
| 12 | def setup(bot): | 13 | def setup(bot): |
| 13 | bot.add_cog(Leave(bot)) \ No newline at end of file | 14 | bot.add_cog(Leave(bot)) |
diff --git a/cogs/music/loop.py b/cogs/music/loop.py index 5f51c7e..2331840 100644 --- a/cogs/music/loop.py +++ b/cogs/music/loop.py | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | from discord.ext import commands | 1 | from discord.ext import commands |
| 2 | 2 | ||
| 3 | |||
| 3 | class Loop(commands.Cog): | 4 | class Loop(commands.Cog): |
| 4 | def __init__(self, bot): | 5 | def __init__(self, bot): |
| 5 | self.bot = bot | 6 | self.bot = bot |
| @@ -18,5 +19,6 @@ class Loop(commands.Cog): | |||
| 18 | self.set_looping(guild_id, looping) | 19 | self.set_looping(guild_id, looping) |
| 19 | await ctx.respond(f"looping jest teraz {'włączony' if looping else 'wyłączony'}.") | 20 | await ctx.respond(f"looping jest teraz {'włączony' if looping else 'wyłączony'}.") |
| 20 | 21 | ||
| 22 | |||
| 21 | def setup(bot): | 23 | def setup(bot): |
| 22 | bot.add_cog(Loop(bot)) \ No newline at end of file | 24 | bot.add_cog(Loop(bot)) |
diff --git a/cogs/music/play.py b/cogs/music/play.py index bf9d081..b47de03 100644 --- a/cogs/music/play.py +++ b/cogs/music/play.py | |||
| @@ -1,12 +1,14 @@ | |||
| 1 | import discord | ||
| 2 | from discord.ext import commands | ||
| 3 | import asyncio | 1 | import asyncio |
| 2 | |||
| 3 | import discord | ||
| 4 | import yt_dlp | 4 | import yt_dlp |
| 5 | from discord.ext import commands | ||
| 5 | from youtubesearchpython import VideosSearch | 6 | from youtubesearchpython import VideosSearch |
| 6 | 7 | ||
| 7 | # Suppress noise about console usage from yt-dlp | 8 | # Suppress noise about console usage from yt-dlp |
| 8 | yt_dlp.utils.bug_reports_message = lambda: '' | 9 | yt_dlp.utils.bug_reports_message = lambda: '' |
| 9 | 10 | ||
| 11 | |||
| 10 | class Play(commands.Cog): | 12 | class Play(commands.Cog): |
| 11 | def __init__(self, bot): | 13 | def __init__(self, bot): |
| 12 | self.bot = bot | 14 | self.bot = bot |
| @@ -32,15 +34,15 @@ class Play(commands.Cog): | |||
| 32 | queue = self.get_queue(guild_id) | 34 | queue = self.get_queue(guild_id) |
| 33 | if queue: | 35 | if queue: |
| 34 | title, url = queue[0] | 36 | title, url = queue[0] |
| 35 | 37 | ||
| 36 | def after_playing(error): | 38 | def after_playing(): |
| 37 | if queue: | 39 | if queue: |
| 38 | queue.pop(0) | 40 | queue.pop(0) |
| 39 | if queue: | 41 | if queue: |
| 40 | next_title, next_url = queue[0] | 42 | next_title, next_url = queue[0] |
| 41 | if not vc.is_playing() and not vc.is_paused(): | 43 | if not vc.is_playing() and not vc.is_paused(): |
| 42 | asyncio.run_coroutine_threadsafe( | 44 | asyncio.run_coroutine_threadsafe( |
| 43 | self.play_audio(ctx, vc, next_url, next_title, guild_id), | 45 | self.play_audio(ctx, vc, next_url, next_title), |
| 44 | self.bot.loop | 46 | self.bot.loop |
| 45 | ) | 47 | ) |
| 46 | else: | 48 | else: |
| @@ -48,11 +50,11 @@ class Play(commands.Cog): | |||
| 48 | vc.disconnect(), | 50 | vc.disconnect(), |
| 49 | self.bot.loop | 51 | self.bot.loop |
| 50 | ) | 52 | ) |
| 51 | 53 | ||
| 52 | if not vc.is_playing() and not vc.is_paused(): | 54 | if not vc.is_playing() and not vc.is_paused(): |
| 53 | await self.play_audio(ctx, vc, url, title, guild_id, after=after_playing) | 55 | await self.play_audio(ctx, vc, url, title, after=after_playing) |
| 54 | 56 | ||
| 55 | async def play_audio(self, ctx, vc, url, title, guild_id, after=None): | 57 | async def play_audio(self, ctx, vc, url, title, after=None): |
| 56 | try: | 58 | try: |
| 57 | with yt_dlp.YoutubeDL(self.ydl_opts) as ydl: | 59 | with yt_dlp.YoutubeDL(self.ydl_opts) as ydl: |
| 58 | info = await self.bot.loop.run_in_executor( | 60 | info = await self.bot.loop.run_in_executor( |
| @@ -61,59 +63,59 @@ class Play(commands.Cog): | |||
| 61 | ) | 63 | ) |
| 62 | if 'entries' in info: | 64 | if 'entries' in info: |
| 63 | info = info['entries'][0] | 65 | info = info['entries'][0] |
| 64 | 66 | ||
| 65 | url2 = info['url'] | 67 | url2 = info['url'] |
| 66 | 68 | ||
| 67 | FFMPEG_OPTIONS = { | 69 | ffmpeg_options = { |
| 68 | 'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', | 70 | 'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', |
| 69 | 'options': '-vn' | 71 | 'options': '-vn' |
| 70 | } | 72 | } |
| 71 | 73 | ||
| 72 | source = discord.FFmpegPCMAudio(url2, **FFMPEG_OPTIONS) | 74 | source = discord.FFmpegPCMAudio(url2, **ffmpeg_options) |
| 73 | vc.play(source, after=after) | 75 | vc.play(source, after=after) |
| 74 | await ctx.followup.send(f"gra: {title}") | 76 | await ctx.followup.send(f"gra: {title}") |
| 75 | except Exception as e: | 77 | except Exception as e: |
| 76 | await ctx.followup.send(f"Wystąpił błąd podczas odtwarzania: {str(e)}") | 78 | await ctx.followup.send(f"Wystąpił błąd podczas odtwarzania: {str(e)}") |
| 77 | # Try to play next in queue if there's an error | 79 | # Try to play next in the queue if there's an error |
| 78 | if after: | 80 | if after: |
| 79 | after(None) | 81 | after(None) |
| 80 | 82 | ||
| 81 | @commands.slash_command(name="grajcuj", description="grajcuj melodyje") | 83 | @commands.slash_command(name="grajcuj", description="grajcuj melodyje") |
| 82 | async def play(self, ctx, *, search: str): | 84 | async def play(self, ctx, *, search: str): |
| 83 | await ctx.defer() | 85 | await ctx.defer() |
| 84 | 86 | ||
| 85 | if not (ctx.author.voice and ctx.author.voice.channel): | 87 | if not (ctx.author.voice and ctx.author.voice.channel): |
| 86 | await ctx.followup.send("nie jesteś w kanale głosowym") | 88 | await ctx.followup.send("nie jesteś w kanale głosowym") |
| 87 | return | 89 | return |
| 88 | 90 | ||
| 89 | channel = ctx.author.voice.channel | 91 | channel = ctx.author.voice.channel |
| 90 | vc = ctx.voice_client or await channel.connect() | 92 | vc = ctx.voice_client or await channel.connect() |
| 91 | 93 | ||
| 92 | if vc.channel != channel: | 94 | if vc.channel != channel: |
| 93 | await vc.move_to(channel) | 95 | await vc.move_to(channel) |
| 94 | 96 | ||
| 95 | # Search for the video | 97 | # Search for the video |
| 96 | videos_search = VideosSearch(search, limit=1) | 98 | videos_search = VideosSearch(search, limit=1) |
| 97 | result = videos_search.result() | 99 | result = videos_search.result() |
| 98 | 100 | ||
| 99 | if not result['result']: | 101 | if not result['result']: |
| 100 | await ctx.followup.send("nie znaleziono wideo dla twojego wyszukiwania.", ephemeral=True) | 102 | await ctx.followup.send("nie znaleziono wideo dla twojego wyszukiwania.", ephemeral=True) |
| 101 | return | 103 | return |
| 102 | 104 | ||
| 103 | video = result['result'][0] | 105 | video = result['result'][0] |
| 104 | title = video['title'] | 106 | title = video['title'] |
| 105 | url = video['link'] | 107 | url = video['link'] |
| 106 | 108 | ||
| 107 | # Add to queue | 109 | # Add to queue |
| 108 | queue = self.get_queue(ctx.guild.id) | 110 | queue = self.get_queue(ctx.guild.id) |
| 109 | queue.append((title, url)) | 111 | queue.append((title, url)) |
| 110 | 112 | ||
| 111 | # If nothing is playing, start playing | 113 | # If nothing is playing, start playing |
| 112 | if not vc.is_playing() and not vc.is_paused(): | 114 | if not vc.is_playing() and not vc.is_paused(): |
| 113 | await self.play_next(ctx, vc, ctx.guild.id) | 115 | await self.play_next(ctx, vc, ctx.guild.id) |
| 114 | else: | 116 | else: |
| 115 | await ctx.followup.send(f"dodano do kolejki: {title}") | 117 | await ctx.followup.send(f"dodano do kolejki: {title}") |
| 116 | 118 | ||
| 117 | @commands.slash_command(name="stop", description="zatrzymaj odtwarzanie i wyczyść kolejkę") | 119 | @commands.slash_command(name="stop", description="zatrzymaj odtwarzanie i wyczyść kolejkę") |
| 118 | async def stop(self, ctx): | 120 | async def stop(self, ctx): |
| 119 | if ctx.voice_client: | 121 | if ctx.voice_client: |
| @@ -123,7 +125,7 @@ class Play(commands.Cog): | |||
| 123 | await ctx.respond("Zatrzymano odtwarzanie i wyczyszczono kolejkę") | 125 | await ctx.respond("Zatrzymano odtwarzanie i wyczyszczono kolejkę") |
| 124 | else: | 126 | else: |
| 125 | await ctx.respond("Nie jestem połączony z kanałem głosowym") | 127 | await ctx.respond("Nie jestem połączony z kanałem głosowym") |
| 126 | 128 | ||
| 127 | @commands.slash_command(name="pauza", description="wstrzymaj odtwarzanie") | 129 | @commands.slash_command(name="pauza", description="wstrzymaj odtwarzanie") |
| 128 | async def pause(self, ctx): | 130 | async def pause(self, ctx): |
| 129 | if ctx.voice_client and ctx.voice_client.is_playing(): | 131 | if ctx.voice_client and ctx.voice_client.is_playing(): |
| @@ -131,7 +133,7 @@ class Play(commands.Cog): | |||
| 131 | await ctx.respond("Wstrzymano odtwarzanie") | 133 | await ctx.respond("Wstrzymano odtwarzanie") |
| 132 | else: | 134 | else: |
| 133 | await ctx.respond("Nic nie jest teraz odtwarzane") | 135 | await ctx.respond("Nic nie jest teraz odtwarzane") |
| 134 | 136 | ||
| 135 | @commands.slash_command(name="wznow", description="wznów odtwarzanie") | 137 | @commands.slash_command(name="wznow", description="wznów odtwarzanie") |
| 136 | async def resume(self, ctx): | 138 | async def resume(self, ctx): |
| 137 | if ctx.voice_client and ctx.voice_client.is_paused(): | 139 | if ctx.voice_client and ctx.voice_client.is_paused(): |
| @@ -140,5 +142,6 @@ class Play(commands.Cog): | |||
| 140 | else: | 142 | else: |
| 141 | await ctx.respond("Nic nie jest teraz wstrzymane") | 143 | await ctx.respond("Nic nie jest teraz wstrzymane") |
| 142 | 144 | ||
| 145 | |||
| 143 | def setup(bot): | 146 | def setup(bot): |
| 144 | bot.add_cog(Play(bot)) \ No newline at end of file | 147 | bot.add_cog(Play(bot)) |
diff --git a/cogs/music/play_compressed.py b/cogs/music/play_compressed.py index 3297110..f14d75b 100644 --- a/cogs/music/play_compressed.py +++ b/cogs/music/play_compressed.py | |||
| @@ -1,15 +1,18 @@ | |||
| 1 | import discord | ||
| 2 | from discord.ext import commands | ||
| 3 | import asyncio | 1 | import asyncio |
| 4 | import os | 2 | import os |
| 5 | import subprocess | 3 | import subprocess |
| 4 | |||
| 5 | import discord | ||
| 6 | from discord.ext import commands | ||
| 6 | from youtubesearchpython import VideosSearch | 7 | from youtubesearchpython import VideosSearch |
| 7 | 8 | ||
| 9 | |||
| 8 | class GrajcujZkompresowane(commands.Cog): | 10 | class GrajcujZkompresowane(commands.Cog): |
| 9 | def __init__(self, bot): | 11 | def __init__(self, bot): |
| 10 | self.bot = bot | 12 | self.bot = bot |
| 11 | 13 | ||
| 12 | def prepend_title_to_file(self, file_path, title): | 14 | @staticmethod |
| 15 | def prepend_title_to_file(file_path, title): | ||
| 13 | try: | 16 | try: |
| 14 | with open(file_path, 'rb') as original: | 17 | with open(file_path, 'rb') as original: |
| 15 | data = original.read() | 18 | data = original.read() |
| @@ -19,7 +22,8 @@ class GrajcujZkompresowane(commands.Cog): | |||
| 19 | except Exception as e: | 22 | except Exception as e: |
| 20 | print(f"Failed to prepend title: {e}") | 23 | print(f"Failed to prepend title: {e}") |
| 21 | 24 | ||
| 22 | def compress_audio(self, input_path): | 25 | @staticmethod |
| 26 | def compress_audio(input_path): | ||
| 23 | base, ext = os.path.splitext(input_path) | 27 | base, ext = os.path.splitext(input_path) |
| 24 | output_path = f"{base}_compressed{ext}" | 28 | output_path = f"{base}_compressed{ext}" |
| 25 | ffmpeg_command = f"ffmpeg -i {input_path} -ar 8000 -ac 1 -b:a 500 -acodec libmp3lame -q:a 9 {output_path}" | 29 | ffmpeg_command = f"ffmpeg -i {input_path} -ar 8000 -ac 1 -b:a 500 -acodec libmp3lame -q:a 9 {output_path}" |
| @@ -84,5 +88,6 @@ class GrajcujZkompresowane(commands.Cog): | |||
| 84 | else: | 88 | else: |
| 85 | await ctx.followup.send(f"dodano do koleyjki (zkompresowane): {title}") | 89 | await ctx.followup.send(f"dodano do koleyjki (zkompresowane): {title}") |
| 86 | 90 | ||
| 91 | |||
| 87 | def setup(bot): | 92 | def setup(bot): |
| 88 | bot.add_cog(GrajcujZkompresowane(bot)) \ No newline at end of file | 93 | bot.add_cog(GrajcujZkompresowane(bot)) |
diff --git a/cogs/music/queue.py b/cogs/music/queue.py index 29f0c36..d932838 100644 --- a/cogs/music/queue.py +++ b/cogs/music/queue.py | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | from discord.ext import commands | 1 | from discord.ext import commands |
| 2 | 2 | ||
| 3 | |||
| 3 | class Queue(commands.Cog): | 4 | class Queue(commands.Cog): |
| 4 | def __init__(self, bot): | 5 | def __init__(self, bot): |
| 5 | self.bot = bot | 6 | self.bot = bot |
| @@ -13,10 +14,11 @@ class Queue(commands.Cog): | |||
| 13 | guild_id = ctx.guild.id | 14 | guild_id = ctx.guild.id |
| 14 | queue = self.get_queue(guild_id) | 15 | queue = self.get_queue(guild_id) |
| 15 | if queue: | 16 | if queue: |
| 16 | queue_str = "\n".join(f"{i+1}. {title}" for i, (_, title, _) in enumerate(queue)) | 17 | queue_str = "\n".join(f"{i + 1}. {title}" for i, (_, title, _) in enumerate(queue)) |
| 17 | await ctx.respond(f"koleyjka:\n{queue_str}") | 18 | await ctx.respond(f"koleyjka:\n{queue_str}") |
| 18 | else: | 19 | else: |
| 19 | await ctx.respond("koleyjka jest pustawa") | 20 | await ctx.respond("koleyjka jest pustawa") |
| 20 | 21 | ||
| 22 | |||
| 21 | def setup(bot): | 23 | def setup(bot): |
| 22 | bot.add_cog(Queue(bot)) \ No newline at end of file | 24 | bot.add_cog(Queue(bot)) |
diff --git a/cogs/music/skip.py b/cogs/music/skip.py index 67c391e..b0023fe 100644 --- a/cogs/music/skip.py +++ b/cogs/music/skip.py | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | from discord.ext import commands | 1 | from discord.ext import commands |
| 2 | import discord | 2 | |
| 3 | 3 | ||
| 4 | class Skip(commands.Cog): | 4 | class Skip(commands.Cog): |
| 5 | def __init__(self, bot): | 5 | def __init__(self, bot): |
| @@ -9,31 +9,31 @@ class Skip(commands.Cog): | |||
| 9 | async def pomin(self, ctx): | 9 | async def pomin(self, ctx): |
| 10 | """Skip the current song and play the next one in the queue.""" | 10 | """Skip the current song and play the next one in the queue.""" |
| 11 | vc = ctx.voice_client | 11 | vc = ctx.voice_client |
| 12 | 12 | ||
| 13 | if not vc or not vc.is_connected(): | 13 | if not vc or not vc.is_connected(): |
| 14 | await ctx.respond("Nie jestem połączony z kanałem głosowym.") | 14 | await ctx.respond("Nie jestem połączony z kanałem głosowym.") |
| 15 | return | 15 | return |
| 16 | 16 | ||
| 17 | if not vc.is_playing() and not vc.is_paused(): | 17 | if not vc.is_playing() and not vc.is_paused(): |
| 18 | await ctx.respond("Nic nie jest teraz odtwarzane.") | 18 | await ctx.respond("Nic nie jest teraz odtwarzane.") |
| 19 | return | 19 | return |
| 20 | 20 | ||
| 21 | # Get the play cog | 21 | # Get the play cog |
| 22 | play_cog = self.bot.get_cog('Play') | 22 | play_cog = self.bot.get_cog('Play') |
| 23 | if not play_cog: | 23 | if not play_cog: |
| 24 | await ctx.respond("Błąd: Nie można znaleźć modułu odtwarzania.") | 24 | await ctx.respond("Błąd: Nie można znaleźć modułu odtwarzania.") |
| 25 | return | 25 | return |
| 26 | 26 | ||
| 27 | queue = play_cog.get_queue(ctx.guild.id) | 27 | queue = play_cog.get_queue(ctx.guild.id) |
| 28 | 28 | ||
| 29 | if not queue: | 29 | if not queue: |
| 30 | await ctx.respond("Kolejka jest pusta.") | 30 | await ctx.respond("Kolejka jest pusta.") |
| 31 | return | 31 | return |
| 32 | 32 | ||
| 33 | # Stop the current song (this will trigger play_next in the after callback) | 33 | # Stop the current song (this will trigger play_next in the after callback) |
| 34 | vc.stop() | 34 | vc.stop() |
| 35 | await ctx.respond("Pominięto aktualną piosenkę.") | 35 | await ctx.respond("Pominięto aktualną piosenkę.") |
| 36 | 36 | ||
| 37 | @commands.slash_command(name="kolejka", description="pokaż aktualną kolejkę") | 37 | @commands.slash_command(name="kolejka", description="pokaż aktualną kolejkę") |
| 38 | async def queue_list(self, ctx): | 38 | async def queue_list(self, ctx): |
| 39 | """Show the current queue.""" | 39 | """Show the current queue.""" |
| @@ -41,21 +41,22 @@ class Skip(commands.Cog): | |||
| 41 | if not play_cog: | 41 | if not play_cog: |
| 42 | await ctx.respond("Błąd: Nie można znaleźć modułu odtwarzania.") | 42 | await ctx.respond("Błąd: Nie można znaleźć modułu odtwarzania.") |
| 43 | return | 43 | return |
| 44 | 44 | ||
| 45 | queue = play_cog.get_queue(ctx.guild.id) | 45 | queue = play_cog.get_queue(ctx.guild.id) |
| 46 | 46 | ||
| 47 | if not queue: | 47 | if not queue: |
| 48 | await ctx.respond("Kolejka jest pusta.") | 48 | await ctx.respond("Kolejka jest pusta.") |
| 49 | return | 49 | return |
| 50 | 50 | ||
| 51 | queue_list = [] | 51 | queue_list = [] |
| 52 | for i, (title, _) in enumerate(queue[:10], 1): # Show up to 10 songs | 52 | for i, (title, _) in enumerate(queue[:10], 1): # Show up to 10 songs |
| 53 | queue_list.append(f"{i}. {title}") | 53 | queue_list.append(f"{i}. {title}") |
| 54 | 54 | ||
| 55 | if len(queue) > 10: | 55 | if len(queue) > 10: |
| 56 | queue_list.append(f"...i {len(queue) - 10} więcej") | 56 | queue_list.append(f"...i {len(queue) - 10} więcej") |
| 57 | 57 | ||
| 58 | await ctx.respond("\n".join(["**Kolejka:**"] + queue_list)) | 58 | await ctx.respond("\n".join(["**Kolejka:**"] + queue_list)) |
| 59 | 59 | ||
| 60 | |||
| 60 | def setup(bot): | 61 | def setup(bot): |
| 61 | bot.add_cog(Skip(bot)) \ No newline at end of file | 62 | bot.add_cog(Skip(bot)) |
diff --git a/cogs/ping_commands.py b/cogs/ping_commands.py deleted file mode 100644 index beb9685..0000000 --- a/cogs/ping_commands.py +++ /dev/null | |||
| @@ -1,60 +0,0 @@ | |||
| 1 | import discord | ||
| 2 | from discord.ext import commands | ||
| 3 | import asyncio | ||
| 4 | from yt_dlp import VideosSearch | ||
| 5 | |||
| 6 | class PingCommands(commands.Cog): | ||
| 7 | def __init__(self, bot): | ||
| 8 | self.bot = bot | ||
| 9 | |||
| 10 | @commands.Cog.command() | ||
| 11 | async def vc(self, ctx): | ||
| 12 | # join voice channel | ||
| 13 | pass | ||
| 14 | |||
| 15 | @commands.slash_command(name="grajcuj", description="grajcuj melodyje") | ||
| 16 | async def play(self, ctx, *, search: str): | ||
| 17 | await ctx.defer() | ||
| 18 | if not (ctx.author.voice and ctx.author.voice.channel): | ||
| 19 | await ctx.followup.send("nie jesteś w kanale głosowym") | ||
| 20 | return | ||
| 21 | channel = ctx.author.voice.channel | ||
| 22 | if ctx.voice_client is not None: | ||
| 23 | vc = ctx.voice_client | ||
| 24 | await vc.move_to(channel) | ||
| 25 | else: | ||
| 26 | vc = await channel.connect() | ||
| 27 | videos_search = VideosSearch(search, limit=1) | ||
| 28 | result = videos_search.result() | ||
| 29 | if not result['result']: | ||
| 30 | await ctx.followup.send("nie znaleziono wideo dla twojego wyszukiwania.", ephemeral=True) | ||
| 31 | return | ||
| 32 | video = result['result'][0] | ||
| 33 | title = video['title'] | ||
| 34 | url = video['link'] | ||
| 35 | |||
| 36 | # Get direct audio stream URL | ||
| 37 | proc = await asyncio.create_subprocess_exec( | ||
| 38 | "yt-dlp", "-f", "bestaudio", "-g", url, | ||
| 39 | stdout=asyncio.subprocess.PIPE | ||
| 40 | ) | ||
| 41 | stdout, _ = await proc.communicate() | ||
| 42 | stream_url = stdout.decode().strip() | ||
| 43 | |||
| 44 | ffmpeg_options = { | ||
| 45 | "before_options": "-probesize 32k -analyzeduration 0 -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5", | ||
| 46 | "options": "-vn" | ||
| 47 | } | ||
| 48 | audio = discord.FFmpegPCMAudio( | ||
| 49 | stream_url, | ||
| 50 | before_options=ffmpeg_options["before_options"], | ||
| 51 | options=ffmpeg_options["options"] | ||
| 52 | ) | ||
| 53 | if not vc.is_playing(): | ||
| 54 | vc.play(audio) | ||
| 55 | await ctx.followup.send(f"gra: {title}") | ||
| 56 | else: | ||
| 57 | await ctx.followup.send(f"dodano do koleyjki: {title}") | ||
| 58 | |||
| 59 | |||
| 60 | |||
diff --git a/cogs/tts.py b/cogs/tts.py index 41dc366..2481ab3 100644 --- a/cogs/tts.py +++ b/cogs/tts.py | |||
| @@ -1,8 +1,10 @@ | |||
| 1 | import datetime | ||
| 2 | import os | ||
| 3 | |||
| 1 | import discord | 4 | import discord |
| 2 | from discord.ext import commands | 5 | from discord.ext import commands |
| 3 | from gtts import gTTS | 6 | from gtts import gTTS |
| 4 | import os | 7 | |
| 5 | import datetime | ||
| 6 | 8 | ||
| 7 | class TTS(commands.Cog): | 9 | class TTS(commands.Cog): |
| 8 | def __init__(self, bot): | 10 | def __init__(self, bot): |
| @@ -10,22 +12,22 @@ class TTS(commands.Cog): | |||
| 10 | 12 | ||
| 11 | @commands.slash_command(name="tts", description="Generuje TTS dla danego tekstu") | 13 | @commands.slash_command(name="tts", description="Generuje TTS dla danego tekstu") |
| 12 | async def tts(self, ctx, | 14 | async def tts(self, ctx, |
| 13 | text: str = discord.Option(str, "Tekst do przeczytania", required=True), | 15 | text: str = discord.Option(str, "Tekst do przeczytania", required=True), |
| 14 | output: str = discord.Option(str, "Wybierz sposób odtwarzania", choices=["file", "vc"], required=True) | 16 | output: str = discord.Option(str, "Wybierz sposób odtwarzania", choices=["file", "vc"], required=True) |
| 15 | ): | 17 | ): |
| 16 | tts = gTTS(text=text, lang='pl') | 18 | tts = gTTS(text=text, lang='pl') |
| 17 | tts.save('tts.mp3') | 19 | tts.save('tts.mp3') |
| 18 | if output == "file": | 20 | if output == "file": |
| 19 | await ctx.respond(file=discord.File('tts.mp3')) | 21 | await ctx.respond(file=discord.File('tts.mp3')) |
| 20 | os.remove('tts.mp3') | 22 | os.remove('tts.mp3') |
| 21 | elif output == "vc": | 23 | elif output == "vc": |
| 22 | # Check if user is in a voice channel | 24 | # Check if the user is in a voice channel |
| 23 | if not (ctx.author.voice and ctx.author.voice.channel): | 25 | if not (ctx.author.voice and ctx.author.voice.channel): |
| 24 | await ctx.respond("Musisz być na kanale głosowym, aby odtworzyć TTS!", ephemeral=True) | 26 | await ctx.respond("Musisz być na kanale głosowym, aby odtworzyć TTS!", ephemeral=True) |
| 25 | os.remove('tts.mp3') | 27 | os.remove('tts.mp3') |
| 26 | return | 28 | return |
| 27 | channel = ctx.author.voice.channel | 29 | channel = ctx.author.voice.channel |
| 28 | # Connect to voice channel if not already connected | 30 | # Connect to the voice channel if not already connected |
| 29 | voice_client = discord.utils.get(self.bot.voice_clients, guild=channel.guild) | 31 | voice_client = discord.utils.get(self.bot.voice_clients, guild=channel.guild) |
| 30 | if not voice_client or not voice_client.is_connected(): | 32 | if not voice_client or not voice_client.is_connected(): |
| 31 | voice_client = await channel.connect() | 33 | voice_client = await channel.connect() |
| @@ -43,5 +45,6 @@ class TTS(commands.Cog): | |||
| 43 | await ctx.respond("Nieznany sposób odtwarzania.", ephemeral=True) | 45 | await ctx.respond("Nieznany sposób odtwarzania.", ephemeral=True) |
| 44 | os.remove('tts.mp3') | 46 | os.remove('tts.mp3') |
| 45 | 47 | ||
| 48 | |||
| 46 | def setup(bot): | 49 | def setup(bot): |
| 47 | bot.add_cog(TTS(bot)) \ No newline at end of file | 50 | bot.add_cog(TTS(bot)) |
diff --git a/cogs/vc_logs.py b/cogs/vclogs.py index e4a8454..4bc7104 100644 --- a/cogs/vc_logs.py +++ b/cogs/vclogs.py | |||
| @@ -1,27 +1,59 @@ | |||
| 1 | import datetime | ||
| 2 | import json | ||
| 3 | import os | ||
| 1 | 4 | ||
| 2 | import discord | 5 | import discord |
| 3 | from discord.ext import commands | 6 | from discord.ext import commands |
| 4 | import datetime | ||
| 5 | from gtts import gTTS | 7 | from gtts import gTTS |
| 6 | import os | ||
| 7 | import json | ||
| 8 | 8 | ||
| 9 | class vc_logs(commands.Cog): | 9 | |
| 10 | class VcLogs(commands.Cog): | ||
| 10 | def __init__(self, bot): | 11 | def __init__(self, bot): |
| 11 | self.bot = bot | 12 | self.bot = bot |
| 12 | 13 | ||
| 14 | @staticmethod | ||
| 15 | async def handle_state_change(member, channel, state_type, is_enabled, current_time, log_channel): | ||
| 16 | """Helper method to handle voice state changes""" | ||
| 17 | state_messages = { | ||
| 18 | 'deaf': { | ||
| 19 | True: ( | ||
| 20 | f"[{current_time}] {member.name} ogłuchnął się na {channel.name}", | ||
| 21 | f"{member.display_name} jest bity przez ojca" | ||
| 22 | ), | ||
| 23 | False: ( | ||
| 24 | f"[{current_time}] {member.name} odgłuchał się na {channel.name}", | ||
| 25 | f"{member.display_name} uciek od ojca" | ||
| 26 | ) | ||
| 27 | }, | ||
| 28 | 'mute': { | ||
| 29 | True: ( | ||
| 30 | f"[{current_time}] {member.name} wyciszył się na {channel.name}", | ||
| 31 | f"{member.display_name} idzie robić jajecznice" | ||
| 32 | ), | ||
| 33 | False: ( | ||
| 34 | f"[{current_time}] {member.name} odciszył się na {channel.name}", | ||
| 35 | f"{member.display_name} zrobił jajecznice" | ||
| 36 | ) | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | message, tts_text = state_messages[state_type][is_enabled] | ||
| 41 | await log_channel.send(message) | ||
| 42 | print(message) | ||
| 43 | return tts_text, channel | ||
| 44 | |||
| 13 | async def play_tts(self, channel, text): | 45 | async def play_tts(self, channel, text): |
| 14 | # Generate TTS audio | 46 | # Generate TTS audio |
| 15 | tts = gTTS(text=text, lang='pl') | 47 | tts = gTTS(text=text, lang='pl') |
| 16 | tts.save('temp_tts.mp3') | 48 | tts.save('temp_tts.mp3') |
| 17 | 49 | ||
| 18 | # Connect to voice channel if not already connected | 50 | # Connect to the voice channel if not already connected |
| 19 | voice_client = discord.utils.get(self.bot.voice_clients, guild=channel.guild) | 51 | voice_client = discord.utils.get(self.bot.voice_clients, guild=channel.guild) |
| 20 | if not voice_client or not voice_client.is_connected(): | 52 | if not voice_client or not voice_client.is_connected(): |
| 21 | voice_client = await channel.connect() | 53 | voice_client = await channel.connect() |
| 22 | elif voice_client.channel != channel: | 54 | elif voice_client.channel != channel: |
| 23 | await voice_client.move_to(channel) | 55 | await voice_client.move_to(channel) |
| 24 | 56 | ||
| 25 | # Play the TTS audio | 57 | # Play the TTS audio |
| 26 | if not voice_client.is_playing(): | 58 | if not voice_client.is_playing(): |
| 27 | if os.path.exists('settings.json'): | 59 | if os.path.exists('settings.json'): |
| @@ -31,7 +63,7 @@ class vc_logs(commands.Cog): | |||
| 31 | else: | 63 | else: |
| 32 | with open('settings.json', 'w') as f: | 64 | with open('settings.json', 'w') as f: |
| 33 | json.dump({'volume': '5'}, f, indent=4) | 65 | json.dump({'volume': '5'}, f, indent=4) |
| 34 | 66 | ||
| 35 | audio_source = discord.FFmpegPCMAudio('temp_tts.mp3', options=f'-filter:a "volume={volume}"') | 67 | audio_source = discord.FFmpegPCMAudio('temp_tts.mp3', options=f'-filter:a "volume={volume}"') |
| 36 | voice_client.play(audio_source) | 68 | voice_client.play(audio_source) |
| 37 | while voice_client.is_playing(): | 69 | while voice_client.is_playing(): |
| @@ -52,8 +84,6 @@ class vc_logs(commands.Cog): | |||
| 52 | except Exception as e: | 84 | except Exception as e: |
| 53 | await ctx.respond(e, ephemeral=True) | 85 | await ctx.respond(e, ephemeral=True) |
| 54 | print(e) | 86 | print(e) |
| 55 | |||
| 56 | |||
| 57 | 87 | ||
| 58 | @commands.Cog.listener() | 88 | @commands.Cog.listener() |
| 59 | async def on_voice_state_update(self, member, before, after): | 89 | async def on_voice_state_update(self, member, before, after): |
| @@ -61,9 +91,11 @@ class vc_logs(commands.Cog): | |||
| 61 | current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") | 91 | current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
| 62 | tts_text = None | 92 | tts_text = None |
| 63 | tts_channel = None | 93 | tts_channel = None |
| 64 | # Ignore if user is a bot | 94 | |
| 95 | # Ignore if the user is a bot | ||
| 65 | if member.bot: | 96 | if member.bot: |
| 66 | return | 97 | return |
| 98 | |||
| 67 | if before.channel is None and after.channel is not None: | 99 | if before.channel is None and after.channel is not None: |
| 68 | message = f"[{current_time}] {member.name} dołączył na {after.channel.name}" | 100 | message = f"[{current_time}] {member.name} dołączył na {after.channel.name}" |
| 69 | tts_text = f"{member.display_name} sie zespawnił" | 101 | tts_text = f"{member.display_name} sie zespawnił" |
| @@ -76,35 +108,23 @@ class vc_logs(commands.Cog): | |||
| 76 | tts_channel = before.channel | 108 | tts_channel = before.channel |
| 77 | await log_channel.send(message) | 109 | await log_channel.send(message) |
| 78 | print(message) | 110 | print(message) |
| 79 | 111 | ||
| 80 | if before.self_deaf != after.self_deaf: | 112 | if before.self_deaf != after.self_deaf: |
| 81 | if after.self_deaf: | 113 | tts_text, tts_channel = await self.handle_state_change( |
| 82 | message = f"[{current_time}] {member.name} ogłuchnął się na {after.channel.name}" | 114 | member, after.channel, 'deaf', after.self_deaf, current_time, log_channel |
| 83 | tts_text = f"{member.display_name} jest bity przez ojca" | 115 | ) |
| 84 | else: | ||
| 85 | message = f"[{current_time}] {member.name} odgłuchął się na {after.channel.name}" | ||
| 86 | tts_text = f"{member.display_name} uciek od ojca" | ||
| 87 | tts_channel = after.channel | ||
| 88 | await log_channel.send(message) | ||
| 89 | print(message) | ||
| 90 | if tts_text and tts_channel: | 116 | if tts_text and tts_channel: |
| 91 | await self.play_tts(tts_channel, tts_text) | 117 | await self.play_tts(tts_channel, tts_text) |
| 92 | return | 118 | return |
| 93 | 119 | ||
| 94 | if before.self_mute != after.self_mute: | 120 | if before.self_mute != after.self_mute: |
| 95 | if after.self_mute: | 121 | tts_text, tts_channel = await self.handle_state_change( |
| 96 | message = f"[{current_time}] {member.name} wyciszył się na {after.channel.name}" | 122 | member, after.channel, 'mute', after.self_mute, current_time, log_channel |
| 97 | tts_text = f"{member.display_name} idzie robić jajecznice" | 123 | ) |
| 98 | else: | 124 | |
| 99 | message = f"[{current_time}] {member.name} odciszył się na {after.channel.name}" | ||
| 100 | tts_text = f"{member.display_name} zrobił jajecznice" | ||
| 101 | tts_channel = after.channel | ||
| 102 | await log_channel.send(message) | ||
| 103 | print(message) | ||
| 104 | |||
| 105 | if tts_text and tts_channel: | 125 | if tts_text and tts_channel: |
| 106 | await self.play_tts(tts_channel, tts_text) | 126 | await self.play_tts(tts_channel, tts_text) |
| 107 | 127 | ||
| 108 | 128 | ||
| 109 | def setup(bot): | 129 | def setup(bot): |
| 110 | bot.add_cog(vc_logs(bot)) \ No newline at end of file | 130 | bot.add_cog(VcLogs(bot)) \ No newline at end of file |
