From 3e44406ce4c7e12628220e369f2f96551acfc74d Mon Sep 17 00:00:00 2001 From: NimVrod Date: Thu, 7 Nov 2024 18:52:45 +0100 Subject: [PATCH 1/7] Added tempvoice command Creates a voice channel in the same category as ctx, Every [delete_after] checks if there are any users in it if not deletes the channel --- pychan/commands/utilities/__init__.py | 2 + pychan/commands/utilities/tempVoice.py | 66 ++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 pychan/commands/utilities/tempVoice.py diff --git a/pychan/commands/utilities/__init__.py b/pychan/commands/utilities/__init__.py index 5c9c75e..2ce0351 100644 --- a/pychan/commands/utilities/__init__.py +++ b/pychan/commands/utilities/__init__.py @@ -1,6 +1,7 @@ from nextcord.ext import commands from .aoc import AoC from .prefix import ChangePrefix +from .tempVoice import TempVoice class Utilities(commands.Cog): @@ -8,3 +9,4 @@ def __init__(self, bot): self.bot = bot self.bot.add_cog(AoC(bot)) self.bot.add_cog(ChangePrefix(bot)) + self.bot.add_cog(TempVoice(bot)) diff --git a/pychan/commands/utilities/tempVoice.py b/pychan/commands/utilities/tempVoice.py new file mode 100644 index 0000000..c5caf4c --- /dev/null +++ b/pychan/commands/utilities/tempVoice.py @@ -0,0 +1,66 @@ +from typing import Union + +import nextcord +from nextcord.ext import commands +import asyncio +import datetime + +class TempVoice(commands.Cog): + def __init__(self, bot): + self.bot = bot + + @commands.group( + pass_context=True, + name="tempvoice", + category="Inne", + usage="create \ndelete ", + help="""Tworzy tymczasowy kanał na długość podaną przez użytkownika""" + ) + async def tempvoice(self, ctx: commands.Context): + + if ctx.invoked_subcommand is None: + await ctx.send_help('tempvoice') + + pass + + + @tempvoice.command() + async def create(self, ctx: commands.Context, delete_after: int = 30): + + try: + vc = await ctx.guild.create_voice_channel(name=f"Temp Voice Channel {datetime.datetime.now().strftime('%H:%m')}", category=ctx.channel.category) + await ctx.send(f"Stworzono {vc.mention}\nJeżeli nikogo nie będzie na kanale za {60*delete_after} minut, zostanie on usunięty") + while True: + await asyncio.sleep(delete_after*60) # in minutes + if vc is None: + break + if len(vc.members) == 0: + await vc.delete() + break + except nextcord.Forbidden: + await ctx.send("Nie mam permisji do stworzenia tego kanału") + + @tempvoice.command() + async def delete(self, ctx: commands.Context, channel: Union[nextcord.VoiceChannel, nextcord.StageChannel, None]): + if channel is None: + channel = ctx.author.voice + if channel is None: + await ctx.send("Nie jesteś na kanale głosowym") + return + + if not channel.name.startswith("Temp Voice Channel"): + await ctx.send("To nie jest tymczasowy kanał głosowy") + return + + try: + await channel.delete() + await ctx.send(f"Usunięto {channel.mention}") + except nextcord.Forbidden: + await ctx.send("Nie mam permisji do usunięcia tego kanału") + + @tempvoice.command() + async def check_permission(self, ctx: commands.Context): + if ctx.guild.me.guild_permissions.manage_channels: + await ctx.send("Mam permisje do zarządzania kanałami") + else: + await ctx.send("Nie mam permisji do zarządzania kanałami") \ No newline at end of file From aa3a29f19318224fc82ac65135a67eba7e72afb8 Mon Sep 17 00:00:00 2001 From: NimVrod Date: Fri, 8 Nov 2024 12:12:16 +0100 Subject: [PATCH 2/7] Added help and aliases to tempvoice command --- pychan/commands/utilities/tempVoice.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pychan/commands/utilities/tempVoice.py b/pychan/commands/utilities/tempVoice.py index c5caf4c..cdd5e0d 100644 --- a/pychan/commands/utilities/tempVoice.py +++ b/pychan/commands/utilities/tempVoice.py @@ -24,7 +24,10 @@ async def tempvoice(self, ctx: commands.Context): pass - @tempvoice.command() + @tempvoice.command( + help="Tworzy tymczasowy kanał głosowy na długość podaną przez użytkownika, domyślnie 30 minut", + aliases = ['c', 'stworz', 's'] + ) async def create(self, ctx: commands.Context, delete_after: int = 30): try: @@ -40,7 +43,10 @@ async def create(self, ctx: commands.Context, delete_after: int = 30): except nextcord.Forbidden: await ctx.send("Nie mam permisji do stworzenia tego kanału") - @tempvoice.command() + @tempvoice.command( + help="Usuwa podany kanał głosowy, jeżeli nie podano kanału, to usuwa kanał na którym jesteś", + aliases = ['d', 'usun', 'u'] + ) async def delete(self, ctx: commands.Context, channel: Union[nextcord.VoiceChannel, nextcord.StageChannel, None]): if channel is None: channel = ctx.author.voice From 3785381ca8912ca8868a62e65f888b2b72c98d36 Mon Sep 17 00:00:00 2001 From: NimVrod Date: Thu, 5 Dec 2024 19:09:09 +0100 Subject: [PATCH 3/7] Add features and fixes to tempVoice.py Changed datetime.now to datetime.today Changed ctx.send to ctx.reply Fixed time issue in reply Added an on_ready check for empty tempvoices in case of bot being offline Added functions in prepartion of adding limits of number of channels for users --- pychan/commands/utilities/tempVoice.py | 57 ++++++++++++++++++++------ 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/pychan/commands/utilities/tempVoice.py b/pychan/commands/utilities/tempVoice.py index cdd5e0d..ef1adbe 100644 --- a/pychan/commands/utilities/tempVoice.py +++ b/pychan/commands/utilities/tempVoice.py @@ -1,7 +1,6 @@ from typing import Union - import nextcord -from nextcord.ext import commands +from nextcord.ext import commands, tasks import asyncio import datetime @@ -31,17 +30,22 @@ async def tempvoice(self, ctx: commands.Context): async def create(self, ctx: commands.Context, delete_after: int = 30): try: - vc = await ctx.guild.create_voice_channel(name=f"Temp Voice Channel {datetime.datetime.now().strftime('%H:%m')}", category=ctx.channel.category) - await ctx.send(f"Stworzono {vc.mention}\nJeżeli nikogo nie będzie na kanale za {60*delete_after} minut, zostanie on usunięty") + vc = await ctx.guild.create_voice_channel(name=f"Temp Voice Channel {datetime.datetime.today().strftime('%H:%M')}", category=ctx.channel.category) + await ctx.reply(f"Stworzono {vc.mention}\nJeżeli nikogo nie będzie na kanale za {delete_after} minut, zostanie on usunięty") while True: await asyncio.sleep(delete_after*60) # in minutes + print(len(vc.members)) if vc is None: break if len(vc.members) == 0: - await vc.delete() + try: + await vc.delete() + except nextcord.NotFound: + #Channel was deleted earlier + pass break except nextcord.Forbidden: - await ctx.send("Nie mam permisji do stworzenia tego kanału") + await ctx.reply("Nie mam permisji do stworzenia tego kanału") @tempvoice.command( help="Usuwa podany kanał głosowy, jeżeli nie podano kanału, to usuwa kanał na którym jesteś", @@ -51,22 +55,49 @@ async def delete(self, ctx: commands.Context, channel: Union[nextcord.VoiceChann if channel is None: channel = ctx.author.voice if channel is None: - await ctx.send("Nie jesteś na kanale głosowym") + await ctx.reply("Nie jesteś na kanale głosowym") return if not channel.name.startswith("Temp Voice Channel"): - await ctx.send("To nie jest tymczasowy kanał głosowy") + await ctx.reply("To nie jest tymczasowy kanał głosowy") return try: + await ctx.reply(f"Usunięto {channel.name}") await channel.delete() - await ctx.send(f"Usunięto {channel.mention}") except nextcord.Forbidden: - await ctx.send("Nie mam permisji do usunięcia tego kanału") + await ctx.reply("Nie mam permisji do usunięcia tego kanału") - @tempvoice.command() + @tempvoice.command( + help="Sprawdź czy bot ma permisje do zarządzania kanałami", + ) async def check_permission(self, ctx: commands.Context): if ctx.guild.me.guild_permissions.manage_channels: - await ctx.send("Mam permisje do zarządzania kanałami") + await ctx.reply("Mam permisje do zarządzania kanałami") else: - await ctx.send("Nie mam permisji do zarządzania kanałami") \ No newline at end of file + await ctx.reply("Nie mam permisji do zarządzania kanałami") + + @tasks.loop(hours=1) + async def check_temp_voice(self): + for guild in self.bot.guilds: + for channel in guild.voice_channels: + if self.check_if_temp_voice_empty(channel): + # TODO + # Implement if no issues are found during testing + + # Danger !!! + #await channel.delete() + print(f"Channel {channel.name} should be deleted") + + + @commands.Cog.listener() + async def on_ready(self): + self.check_temp_voice.start() + + def check_if_temp_voice_empty(self, channel: nextcord.VoiceChannel): + return len(channel.members) <= 0 and channel.name.startswith("Temp Voice Channel") + + def extract_params_from_name(self, name: str): + # TODO + # If limit per user is implemented + pass From d9f92a9e8990bf2486d47e6a9b8776d6f5fbc4f3 Mon Sep 17 00:00:00 2001 From: NimVrod Date: Fri, 6 Dec 2024 16:01:30 +0100 Subject: [PATCH 4/7] Added a simple limit to tempvoice channels 1 channel per user can be created at a time Removed unneeded functions --- pychan/commands/utilities/tempVoice.py | 29 +++++++++++++++++++------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/pychan/commands/utilities/tempVoice.py b/pychan/commands/utilities/tempVoice.py index ef1adbe..9770c43 100644 --- a/pychan/commands/utilities/tempVoice.py +++ b/pychan/commands/utilities/tempVoice.py @@ -4,9 +4,11 @@ import asyncio import datetime + class TempVoice(commands.Cog): def __init__(self, bot): self.bot = bot + self.list = {} @commands.group( pass_context=True, @@ -30,18 +32,25 @@ async def tempvoice(self, ctx: commands.Context): async def create(self, ctx: commands.Context, delete_after: int = 30): try: + if ctx.author.id in self.list: + await ctx.reply("Możesz stworzyć tylko jeden tymczasowy kanał na raz") + return + vc = await ctx.guild.create_voice_channel(name=f"Temp Voice Channel {datetime.datetime.today().strftime('%H:%M')}", category=ctx.channel.category) + self.list[ctx.author.id] = vc.id await ctx.reply(f"Stworzono {vc.mention}\nJeżeli nikogo nie będzie na kanale za {delete_after} minut, zostanie on usunięty") while True: await asyncio.sleep(delete_after*60) # in minutes - print(len(vc.members)) if vc is None: break if len(vc.members) == 0: try: await vc.delete() + self.list.pop(ctx.author.id) except nextcord.NotFound: #Channel was deleted earlier + if ctx.author.id in self.list: + self.list.pop(ctx.author.id) pass break except nextcord.Forbidden: @@ -53,7 +62,7 @@ async def create(self, ctx: commands.Context, delete_after: int = 30): ) async def delete(self, ctx: commands.Context, channel: Union[nextcord.VoiceChannel, nextcord.StageChannel, None]): if channel is None: - channel = ctx.author.voice + channel = ctx.author.voice.channel if channel is None: await ctx.reply("Nie jesteś na kanale głosowym") return @@ -64,6 +73,10 @@ async def delete(self, ctx: commands.Context, channel: Union[nextcord.VoiceChann try: await ctx.reply(f"Usunięto {channel.name}") + #Find channel in limit list and delete it + for key in self.list: + if self.list[key] == channel.id: + del self.list[key] await channel.delete() except nextcord.Forbidden: await ctx.reply("Nie mam permisji do usunięcia tego kanału") @@ -79,9 +92,10 @@ async def check_permission(self, ctx: commands.Context): @tasks.loop(hours=1) async def check_temp_voice(self): + # Might remove the loop and only check it on on_ready as it might break the limit function for guild in self.bot.guilds: for channel in guild.voice_channels: - if self.check_if_temp_voice_empty(channel): + if self.check_if_temp_voice_empty(channel) and self.is_channel_overdue(channel): # TODO # Implement if no issues are found during testing @@ -96,8 +110,7 @@ async def on_ready(self): def check_if_temp_voice_empty(self, channel: nextcord.VoiceChannel): return len(channel.members) <= 0 and channel.name.startswith("Temp Voice Channel") - - def extract_params_from_name(self, name: str): - # TODO - # If limit per user is implemented - pass + + def is_channel_overdue(self, channel: nextcord.VoiceChannel): + # Checks if channel is older than 1 hour + return channel.created_at - datetime.datetime.now(datetime.UTC) > datetime.timedelta(hours=1) \ No newline at end of file From 6c5bf365c384d61b76ec20736ea0d146be795249 Mon Sep 17 00:00:00 2001 From: NimVrod Date: Fri, 6 Dec 2024 20:40:55 +0100 Subject: [PATCH 5/7] Fix comments --- pychan/commands/utilities/tempVoice.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pychan/commands/utilities/tempVoice.py b/pychan/commands/utilities/tempVoice.py index 9770c43..dfd7cab 100644 --- a/pychan/commands/utilities/tempVoice.py +++ b/pychan/commands/utilities/tempVoice.py @@ -76,7 +76,7 @@ async def delete(self, ctx: commands.Context, channel: Union[nextcord.VoiceChann #Find channel in limit list and delete it for key in self.list: if self.list[key] == channel.id: - del self.list[key] + self.list.pop(key) await channel.delete() except nextcord.Forbidden: await ctx.reply("Nie mam permisji do usunięcia tego kanału") @@ -92,7 +92,6 @@ async def check_permission(self, ctx: commands.Context): @tasks.loop(hours=1) async def check_temp_voice(self): - # Might remove the loop and only check it on on_ready as it might break the limit function for guild in self.bot.guilds: for channel in guild.voice_channels: if self.check_if_temp_voice_empty(channel) and self.is_channel_overdue(channel): @@ -112,5 +111,5 @@ def check_if_temp_voice_empty(self, channel: nextcord.VoiceChannel): return len(channel.members) <= 0 and channel.name.startswith("Temp Voice Channel") def is_channel_overdue(self, channel: nextcord.VoiceChannel): - # Checks if channel is older than 1 hour + """Checks if channel is older than 1 hour""" return channel.created_at - datetime.datetime.now(datetime.UTC) > datetime.timedelta(hours=1) \ No newline at end of file From 701526445bf4817859de2cbdf86485cc726b1025 Mon Sep 17 00:00:00 2001 From: NimVrod Date: Sat, 7 Dec 2024 12:55:56 +0100 Subject: [PATCH 6/7] Added limit to tempvoice Moved finding a user_id from channel_id to a separate function --- pychan/commands/utilities/tempVoice.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/pychan/commands/utilities/tempVoice.py b/pychan/commands/utilities/tempVoice.py index dfd7cab..813ae7c 100644 --- a/pychan/commands/utilities/tempVoice.py +++ b/pychan/commands/utilities/tempVoice.py @@ -74,9 +74,9 @@ async def delete(self, ctx: commands.Context, channel: Union[nextcord.VoiceChann try: await ctx.reply(f"Usunięto {channel.name}") #Find channel in limit list and delete it - for key in self.list: - if self.list[key] == channel.id: - self.list.pop(key) + key = self.get_user_id_from_channel_id(channel.id) + if key: + self.list.pop(key) await channel.delete() except nextcord.Forbidden: await ctx.reply("Nie mam permisji do usunięcia tego kanału") @@ -99,7 +99,13 @@ async def check_temp_voice(self): # Implement if no issues are found during testing # Danger !!! - #await channel.delete() + """ + key = self.get_user_id_from_channel_id(channel.id) + if key: + self.list.pop(key) + await channel.delete() + """ + print(f"Channel {channel.name} should be deleted") @@ -112,4 +118,11 @@ def check_if_temp_voice_empty(self, channel: nextcord.VoiceChannel): def is_channel_overdue(self, channel: nextcord.VoiceChannel): """Checks if channel is older than 1 hour""" - return channel.created_at - datetime.datetime.now(datetime.UTC) > datetime.timedelta(hours=1) \ No newline at end of file + return channel.created_at - datetime.datetime.now(datetime.UTC) > datetime.timedelta(hours=1) + + def get_user_id_from_channel_id(self, channel_id: int) -> Union[int, None]: + for key in self.list: + if self.list[key] == channel_id: + return key + + return None \ No newline at end of file From 8e5a96364244955e911ff0c02fc191577dd36130 Mon Sep 17 00:00:00 2001 From: NimVrod Date: Sat, 7 Dec 2024 13:03:37 +0100 Subject: [PATCH 7/7] Add comments and types to util functions --- pychan/commands/utilities/tempVoice.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pychan/commands/utilities/tempVoice.py b/pychan/commands/utilities/tempVoice.py index 813ae7c..cbba28e 100644 --- a/pychan/commands/utilities/tempVoice.py +++ b/pychan/commands/utilities/tempVoice.py @@ -113,14 +113,19 @@ async def check_temp_voice(self): async def on_ready(self): self.check_temp_voice.start() - def check_if_temp_voice_empty(self, channel: nextcord.VoiceChannel): + def check_if_temp_voice_empty(self, channel: nextcord.VoiceChannel) -> bool: + """Checks if channel is a temp voice channel and if there is no memebers connected to it""" return len(channel.members) <= 0 and channel.name.startswith("Temp Voice Channel") - def is_channel_overdue(self, channel: nextcord.VoiceChannel): + def is_channel_overdue(self, channel: nextcord.VoiceChannel) -> bool: """Checks if channel is older than 1 hour""" return channel.created_at - datetime.datetime.now(datetime.UTC) > datetime.timedelta(hours=1) def get_user_id_from_channel_id(self, channel_id: int) -> Union[int, None]: + """ + Returns user_id of a temp voice channel author + Returns None if no author is found + """ for key in self.list: if self.list[key] == channel_id: return key