WIP: Add TTS cog #18
7 changed files with 1492 additions and 198 deletions
1517
poetry.lock
generated
1517
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -17,6 +17,7 @@ numpy = "^1.26.4"
|
||||||
colorthief = "^0.2.1"
|
colorthief = "^0.2.1"
|
||||||
beautifulsoup4 = "^4.12.3"
|
beautifulsoup4 = "^4.12.3"
|
||||||
markdownify = "^0.12.1"
|
markdownify = "^0.12.1"
|
||||||
|
py-lav = {extras = ["all"], version = ">=1.14.3,<1.15"}
|
||||||
|
|
||||||
[tool.poetry.group.dev]
|
[tool.poetry.group.dev]
|
||||||
optional = true
|
optional = true
|
||||||
|
|
12
tts/__init__.py
Normal file
12
tts/__init__.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pylav.extension.red.utils.required_methods import pylav_auto_setup
|
||||||
|
from pylav.type_hints.bot import DISCORD_BOT_TYPE
|
||||||
|
from redbot.core.utils import get_end_user_data_statement
|
||||||
|
|
||||||
|
from .tts import TTS
|
||||||
|
|
||||||
|
__red_end_user_data_statement__ = get_end_user_data_statement(__file__)
|
||||||
|
|
||||||
|
async def setup(bot: DISCORD_BOT_TYPE):
|
||||||
|
await pylav_auto_setup(bot, TTS)
|
14
tts/config.py
Normal file
14
tts/config.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
from redbot.core import Config
|
||||||
|
|
||||||
|
config: Config = Config.get_conf(None, identifier=69737245070283, cog_name="TTS")
|
||||||
|
|
||||||
|
|
||||||
|
def register_config(config_obj: Config):
|
||||||
|
config_obj.register_global(
|
||||||
|
use_google_tts = False,
|
||||||
|
)
|
||||||
|
config_obj.register_guild(
|
||||||
|
enabled_channels = [],
|
||||||
|
announce = False,
|
||||||
|
voice_channels = True
|
||||||
|
)
|
21
tts/info.json
Normal file
21
tts/info.json
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"author" : ["SeaswimmerTheFsh (seasw.)"],
|
||||||
|
"install_msg" : "Thank you for installing TTS!\nPlease read the [documentation](https://seacogs.coastalcommits.com/tts) for more information.\nYou can find the source code of this cog [here](https://coastalcommits.com/SeaswimmerTheFsh/SeaCogs).",
|
||||||
|
"name" : "TTS",
|
||||||
|
"short" : "Text to Speech through Pylav",
|
||||||
|
"description" : "Text to Speech through Pylav",
|
||||||
|
"end_user_data_statement" : "This cog does not store end user data.",
|
||||||
|
"hidden": false,
|
||||||
|
"disabled": false,
|
||||||
|
"min_bot_version": "3.5.0",
|
||||||
|
"min_python_version": [3, 11, 0],
|
||||||
|
"requirements": [
|
||||||
|
"Py-Lav[all]"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"pylav",
|
||||||
|
"audio",
|
||||||
|
"tts"
|
||||||
|
],
|
||||||
|
"required_cogs": {"audio" : "https://github.com/PyLav/Red-Cogs"}
|
||||||
|
}
|
68
tts/menu.py
Normal file
68
tts/menu.py
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
from discord import ButtonStyle, Embed, Interaction, ui
|
||||||
|
from redbot.core import commands
|
||||||
|
from redbot.core.utils.chat_formatting import bold
|
||||||
|
|
||||||
|
from tts.config import config
|
||||||
|
|
||||||
|
|
||||||
|
class Menu(ui.View):
|
||||||
|
def __init__(self, ctx: commands.Context):
|
||||||
|
super().__init__()
|
||||||
|
self.ctx = ctx
|
||||||
|
|
||||||
|
@ui.button(label="Announce", style=ButtonStyle.green, row=0)
|
||||||
|
async def announce(self, interaction: Interaction, button: ui.Button):
|
||||||
|
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
|
||||||
|
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
|
||||||
|
return
|
||||||
|
await interaction.response.defer()
|
||||||
|
current_setting = await config.guild(interaction.guild).announce
|
||||||
|
await config.guild(interaction.guild).announce.set(not current_setting)
|
||||||
|
await interaction.message.edit(embed=await embed(self.ctx))
|
||||||
|
|
||||||
|
@ui.button(label="Use Voice Channels", style=ButtonStyle.green, row=0)
|
||||||
|
async def voice_channels(self, interaction: Interaction, button: ui.Button):
|
||||||
|
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
|
||||||
|
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
|
||||||
|
return
|
||||||
|
await interaction.response.defer()
|
||||||
|
current_setting = await config.guild(interaction.guild).voice_channels()
|
||||||
|
await config.guild(interaction.guild).voice_channels.set(not current_setting)
|
||||||
|
await interaction.message.edit(embed=await embed(self.ctx))
|
||||||
|
|
||||||
|
@ui.select(placeholder="Enabled Channels", cls=ui.ChannelSelect, row=1)
|
||||||
|
async def log_channel(self, interaction: Interaction, select: ui.ChannelSelect):
|
||||||
|
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
|
||||||
|
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
|
||||||
|
return
|
||||||
|
await interaction.response.defer()
|
||||||
|
channels: list = await config.guild(interaction.guild).enabled_channels()
|
||||||
|
if select.values[0] in channels:
|
||||||
|
channels.remove(select.values[0])
|
||||||
|
else:
|
||||||
|
channels.append(select.values[0])
|
||||||
|
await config.guild(interaction.guild).enabled_channels.set(channels)
|
||||||
|
await interaction.message.edit(embed=await embed(self.ctx))
|
||||||
|
|
||||||
|
async def embed(ctx: commands.Context):
|
||||||
|
embed = Embed(title="TTS Settings", color=ctx.embed_color)
|
||||||
|
override_settings = {
|
||||||
|
"announce": await config.guild(ctx.guild).announce(),
|
||||||
|
"voice_channels": await config.guild(ctx.guild).voice_channels(),
|
||||||
|
"enabled_channels": await config.guild(ctx.guild).enabled_channels(),
|
||||||
|
}
|
||||||
|
|
||||||
|
override_str = [
|
||||||
|
"- " + bold("Announce: ") + get_bool_emoji(override_settings["announce"]),
|
||||||
|
"- " + bold("Voice Channels: ") + get_bool_emoji(override_settings["voice_channels"]),
|
||||||
|
"- " + ", ".join([f"<#{channel}>" for channel in override_settings["voice_channels"]])
|
||||||
|
]
|
||||||
|
embed.description = "\n".join(override_str)
|
||||||
|
|
||||||
|
def get_bool_emoji(value: bool) -> str:
|
||||||
|
"""Returns a unicode emoji based on a boolean value."""
|
||||||
|
if value is True:
|
||||||
|
return "\N{WHITE HEAVY CHECK MARK}"
|
||||||
|
if value is False:
|
||||||
|
return "\N{NO ENTRY SIGN}"
|
||||||
|
return "\N{BLACK QUESTION MARK ORNAMENT}\N{VARIATION SELECTOR-16}"
|
57
tts/tts.py
Normal file
57
tts/tts.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
# _____ _
|
||||||
|
# / ____| (_)
|
||||||
|
# | (___ ___ __ _ _____ ___ _ __ ___ _ __ ___ ___ _ __
|
||||||
|
# \___ \ / _ \/ _` / __\ \ /\ / / | '_ ` _ \| '_ ` _ \ / _ \ '__|
|
||||||
|
# ____) | __/ (_| \__ \\ V V /| | | | | | | | | | | | __/ |
|
||||||
|
# |_____/ \___|\__,_|___/ \_/\_/ |_|_| |_| |_|_| |_| |_|\___|_|
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from discord import Message
|
||||||
|
from redbot.core import commands
|
||||||
|
from redbot.core.bot import Red
|
||||||
|
|
||||||
|
from tts.config import config
|
||||||
|
from tts.menu import Menu, embed
|
||||||
|
|
||||||
|
|
||||||
|
class TTS(commands.Cog):
|
||||||
|
"""Text to Speech through Pylav"""
|
||||||
|
|
||||||
|
def __init__(self, bot: Red):
|
||||||
|
self.bot = bot
|
||||||
|
self.logger = logging.getLogger("red.sea.tts")
|
||||||
|
|
||||||
|
async def on_message(self, message: Message):
|
||||||
|
await self.bot.wait_until_red_ready()
|
||||||
|
if message.author.bot:
|
||||||
|
return
|
||||||
|
if message.guild is None:
|
||||||
|
return
|
||||||
|
valid_prefixes = await self.bot.get_valid_prefixes(message.guild)
|
||||||
|
valid_prefixes.append("\\")
|
||||||
|
if any(message.content.startswith(prefix) for prefix in valid_prefixes):
|
||||||
|
return
|
||||||
|
if message.channel.id in await self.config.guild(message.guild).enabled_channels():
|
||||||
|
pylav = self.bot.get_cog("PyLavPlayer")
|
||||||
|
if pylav is None:
|
||||||
|
self.logger.error("PyLav is not loaded, so TTS is not available.")
|
||||||
|
await message.reply("PyLav is not loaded, so TTS is not available.\nPlease report this to the bot owner.\nIf you are the bot owner, see [https://github.com/PyLav/Red-Cogs](PyLav/RedCogs) for more information.")
|
||||||
|
return
|
||||||
|
#TODO - add PyLav integration
|
||||||
|
return
|
||||||
|
|
||||||
|
@commands.group(name="tts")
|
||||||
|
@commands.admin_or_permissions(manage_guild=True)
|
||||||
|
async def tts(self, ctx: commands.Context):
|
||||||
|
"""Text to Speech settings"""
|
||||||
|
await ctx.send(embed=await embed(ctx), view=Menu(ctx))
|
||||||
|
|
||||||
|
@tts.command(name="google")
|
||||||
|
@commands.is_owner()
|
||||||
|
async def tts_google(self, ctx: commands.Context, enable: bool = None):
|
||||||
|
"""Enable or disable Google Cloud TTS"""
|
||||||
|
if enable is None:
|
||||||
|
enable = not await config.use_google_tts()
|
||||||
|
await config.use_google_tts.set(enable)
|
||||||
|
await ctx.send(f"Google TTS has been {'enabled' if enable else 'disabled'}.")
|
Loading…
Reference in a new issue