Skip to content

Commit

Permalink
Merge branch 'develop' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Rivixer committed Jun 29, 2023
2 parents dc3e8f4 + bd350f5 commit 3d00cbb
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 50 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,6 @@ old_settings/
old_files/
settings.json
prototype_json.json
category_ids.json
voice_channel_names.txt

# Registraion
registered_users.json
Expand Down
2 changes: 1 addition & 1 deletion sggwbot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
__author__ = "Wiktor Jaworski"
__license__ = "MIT"
__copyright__ = "Copyright 2023 Wiktor Jaworski"
__version__ = "0.7.0"
__version__ = "0.7.1"
4 changes: 4 additions & 0 deletions sggwbot/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ class RegistrationError(SGGWBotError):

class AttachmentError(SGGWBotError):
"""Attachment error."""


class NoVoiceConnection(SGGWBotError):
"""No voice connection."""
116 changes: 69 additions & 47 deletions sggwbot/voice_channel_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from __future__ import annotations

import asyncio
import json
import random

import nextcord
Expand All @@ -22,7 +21,8 @@
from nextcord.interactions import Interaction
from nextcord.member import Member, VoiceState

from sggwbot.console import Console
from sggwbot.console import Console, FontColour
from sggwbot.errors import NoVoiceConnection
from sggwbot.models import Controller, Model
from sggwbot.sggw_bot import SGGWBot
from sggwbot.utils import InteractionUtils
Expand Down Expand Up @@ -66,20 +66,45 @@ async def _on_voice_state_update(
if member.bot or before.channel == after.channel:
return

if (
after.channel
and after.channel.category == self._model.voice_channel_category
and len(after.channel.members) == 1
):
await self._ctrl.create_new_channel()

if (
before.channel
and before.channel.category == self._model.voice_channel_category
and len(list(map(lambda i: not i.bot, before.channel.members))) == 0
and any(filter(lambda i: len(i.members) == 0, before.channel.category.channels)) # type: ignore
):
await self._ctrl.delete_voice_channel(before.channel) # type: ignore
if before.channel:
Console.specific(
f"{member.display_name} left.",
before.channel.name,
FontColour.BLUE,
bold_type=True,
)
if (
before.channel.category == self._model.voice_channel_category
and len(list(map(lambda i: not i.bot, before.channel.members))) == 0
and any(filter(lambda i: len(i.members) == 0, before.channel.category.channels)) # type: ignore
):
channel_name = before.channel.name
await self._ctrl.delete_voice_channel(before.channel) # type: ignore
Console.specific(
"Channel has been deleted.",
channel_name,
FontColour.BLUE,
bold_type=True,
)

if after.channel:
Console.specific(
f"{member.display_name} joined.",
after.channel.name,
FontColour.BLUE,
bold_type=True,
)
if (
after.channel.category == self._model.voice_channel_category
and len(after.channel.members) == 1
):
created_channel = await self._ctrl.create_new_channel()
Console.specific(
"Channel has been created.",
created_channel.name,
FontColour.BLUE,
bold_type=True,
)

@nextcord.slash_command(
name="limit",
Expand All @@ -89,6 +114,8 @@ async def _on_voice_state_update(
before="Changing the limit to {limit}...",
after="The limit has been changed.",
catch_errors=True,
with_traceback=False,
additional_errors=[NoVoiceConnection],
)
@InteractionUtils.with_log()
async def _limit(
Expand All @@ -108,6 +135,11 @@ async def _limit(
The interaction that triggered the command.
limit: :class:`int`
The limit to be set.
Raises
------
NoVoiceConnection
If the member is not connected to a voice channel.
"""

user: Member = interaction.user # type: ignore
Expand All @@ -118,7 +150,7 @@ async def _limit(
or not interaction.channel
or not self._model.user_on_voice(user)
):
return
raise NoVoiceConnection("You are not connected to a voice channel.")

await voice.channel.edit(user_limit=limit) # type: ignore

Expand All @@ -131,7 +163,7 @@ async def _limit(
after="The name has been changed.",
catch_errors=True,
with_traceback=False,
additional_errors=[TimeoutError],
additional_errors=[TimeoutError, NoVoiceConnection],
)
@InteractionUtils.with_log()
async def _name(
Expand All @@ -156,6 +188,8 @@ async def _name(
------
TimeoutError
If the name of the channel has been changed 2 times per 10 minutes.
NoVoiceConnection
If the member is not connected to a voice channel.
"""

user: Member = interaction.user # type: ignore
Expand All @@ -166,7 +200,7 @@ async def _name(
or not interaction.channel
or not self._model.user_on_voice(user)
):
return
raise NoVoiceConnection("You are not connected to a voice channel.")

try:
await asyncio.wait_for(
Expand Down Expand Up @@ -215,13 +249,14 @@ def __init__(self, model: VoiceChannelManagerModel) -> None:
super().__init__(model)
self._model = model

async def create_new_channel(self):
async def create_new_channel(self) -> VoiceChannel:
"""Creates a new voice channel."""
category = self._model.voice_channel_category
name = self._model.get_next_voice_channel_name()
await category.create_voice_channel(name=name)
channel = await category.create_voice_channel(name=name)
return channel

async def delete_voice_channel(self, channel: VoiceChannel):
async def delete_voice_channel(self, channel: VoiceChannel) -> None:
"""Deletes a voice channel.
Parameters
Expand All @@ -233,7 +268,7 @@ async def delete_voice_channel(self, channel: VoiceChannel):
if isinstance(channel, VoiceChannel):
await channel.delete()

async def change_channel_name(self, channel: VoiceChannel, name: str):
async def change_channel_name(self, channel: VoiceChannel, name: str) -> None:
"""Changes the name of a voice channel.
Parameters
Expand All @@ -249,22 +284,24 @@ async def change_channel_name(self, channel: VoiceChannel, name: str):
class VoiceChannelManagerModel(Model):
"""The model for the voice channel manager cog."""

__slots__ = (
"_voice_channel_category_id",
"_voice_channel_names",
"_bot",
)
__slots__ = ("_bot",)

_bot: SGGWBot
_voice_channel_category_id: int
_voice_channel_names: list[str]

def __init__(self, bot: SGGWBot) -> None:
"""Initializes the voice channel manager model."""
super().__init__()
self._bot = bot
self._load_voice_channel_names()
self._load_voice_channel_category_id()

@property
def _voice_channel_category_id(self) -> int:
"""The voice channel category id."""
return self.data["voice_channel_category_id"]

@property
def _voice_channel_names(self) -> list[str]:
"""The voice channel names."""
return self.data["default_voice_channel_names"]

def user_on_voice(self, user: Member) -> bool:
"""Returns whether the user is on voice."""
Expand All @@ -285,11 +322,6 @@ def voice_channel_category(self) -> CategoryChannel:
)
)[0]

def _load_voice_channel_category_id(self) -> None:
with open("data/category_ids.json", "r", encoding="utf-8") as file:
data = json.load(file)
self._voice_channel_category_id = data["voice_channels"]

def get_voice_channels(self) -> list[VoiceChannel]:
"""Returns a list of voice channels in the voice channel category."""
guild = self._bot.get_default_guild()
Expand All @@ -300,16 +332,6 @@ def get_voice_channels(self) -> list[VoiceChannel]:
)
)

def _load_voice_channel_names(self) -> None:
path = "data/voice_channel_names.txt"
try:
with open(path, "r", encoding="utf-8") as file:
channel_names = map(lambda line: line.strip(), file.readlines())
except OSError:
Console.warn(f"File '{path}' not found.")
channel_names = []
self._voice_channel_names = list(filter(None, channel_names))

def _voice_channel_name_exists(self, name: str) -> bool:
voice_channels = self.get_voice_channels()
for voice_channel in voice_channels:
Expand Down

0 comments on commit 3d00cbb

Please sign in to comment.