Files
och-bot/lib/utils.py

72 lines
2.4 KiB
Python

import asyncio
import os
import random
import string
from collections import AsyncIterable
from typing import Callable, AsyncGenerator, Optional, Any, Coroutine
import discord
import gtts
async def async_filter(fun: Callable, iterable: AsyncIterable) -> AsyncGenerator:
async for val in iterable:
if fun(val):
yield val
def find_category(guild: discord.Guild, group: str) -> Optional[discord.CategoryChannel]:
group = group.lower()
for cat in guild.categories:
if cat.name.lower() == group:
return cat
return None
async def find_role_case_insensitive(guild: discord.Guild, name: str, prefix: str = '') -> Optional[discord.Role]:
for role in await guild.fetch_roles():
if name.strip().lower() == role.name[len(prefix):].lower():
return role
return None
def link_channel(channel: discord.abc.GuildChannel, italic: bool = False) -> str:
if italic:
return '[*' + channel.name + '*](https://discord.com/channels/' + str(channel.guild.id) + '/' + str(
channel.id) + ')'
return '[' + channel.name + '](https://discord.com/channels/' + str(channel.guild.id) + '/' + str(channel.id) + ')'
def text_to_speech(text: str, lang: str = "de") -> (discord.AudioSource, Callable[[], None]):
tts = gtts.gTTS(text, lang=lang)
os.makedirs('temp', exist_ok=True)
file_name = 'temp/' + ''.join(random.choice(string.ascii_lowercase) for i in range(12)) + '.mp3'
tts.save(file_name)
source = discord.PCMVolumeTransformer(
discord.FFmpegPCMAudio(source=file_name, before_options='-v quiet')
)
def destroy():
os.remove(file_name)
return source, destroy
async def connect_and_play(
channel: discord.VoiceChannel, source: discord.AudioSource,
after_play: Optional[Callable[[discord.DiscordException, discord.VoiceProtocol], Coroutine[Any, Any, Any]]] = None
) -> Optional[discord.VoiceProtocol]:
# noinspection PyTypeChecker
client: discord.VoiceClient = await channel.connect()
after_callback: Optional[Callable[[discord.DiscordException], Any]]
if after_play is None:
after_callback = None
else:
def callback(exc: discord.DiscordException) -> Any:
loop = asyncio.get_event_loop()
return loop.run_until_complete(after_play(exc, client))
after_callback = callback
client.play(source, after=after_callback)
return client