mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-12-03 16:24:20 +00:00
Managed to get Play working
This commit is contained in:
parent
4c82a7bf1b
commit
ca0caecb85
7 changed files with 126 additions and 74 deletions
22
poetry.lock
generated
22
poetry.lock
generated
|
@ -268,6 +268,17 @@ version = "2.8.1"
|
|||
[package.dependencies]
|
||||
six = ">=1.5"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "A streaming multipart parser for Python"
|
||||
name = "python-multipart"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "0.0.5"
|
||||
|
||||
[package.dependencies]
|
||||
six = ">=1.4.0"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "We have made you a wrapper you can't refuse"
|
||||
|
@ -366,6 +377,10 @@ version = "^2.8.4"
|
|||
optional = true
|
||||
version = "^1.3.0"
|
||||
|
||||
[package.dependencies.python-multipart]
|
||||
optional = true
|
||||
version = "^0.0.5"
|
||||
|
||||
[package.dependencies.python_telegram_bot]
|
||||
optional = true
|
||||
version = "^12.2.0"
|
||||
|
@ -399,14 +414,14 @@ alchemy_easy = ["sqlalchemy (^1.3.10)", "psycopg2_binary (^2.8.4)"]
|
|||
alchemy_hard = ["sqlalchemy (^1.3.10)", "psycopg2 (^2.8.4)"]
|
||||
bard = ["ffmpeg_python (~0.2.0)", "youtube-dl"]
|
||||
coloredlogs = ["coloredlogs (^10.0)"]
|
||||
constellation = ["starlette (^0.12.13)", "uvicorn (^0.10.7)"]
|
||||
constellation = ["starlette (^0.12.13)", "uvicorn (^0.10.7)", "python-multipart (^0.0.5)"]
|
||||
discord = ["discord.py", "pynacl (^1.3.0)"]
|
||||
herald = ["websockets (^8.1)"]
|
||||
sentry = ["sentry_sdk (~0.13.2)"]
|
||||
telegram = ["python_telegram_bot (^12.2.0)"]
|
||||
|
||||
[package.source]
|
||||
reference = "f1803f2ffd5507827be1a430d2b09996decfc098"
|
||||
reference = "8ff0731aa5bd167a59f342472bfe2d7e74daf1ca"
|
||||
type = "git"
|
||||
url = "https://github.com/Steffo99/royalnet/"
|
||||
|
||||
|
@ -787,6 +802,9 @@ python-dateutil = [
|
|||
{file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"},
|
||||
{file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
|
||||
]
|
||||
python-multipart = [
|
||||
{file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"},
|
||||
]
|
||||
python-telegram-bot = [
|
||||
{file = "python-telegram-bot-12.2.0.tar.gz", hash = "sha256:346d42771c2b23384c59f5f41e05bd7e801a0ce118d8dcb95209bb73d5f694c5"},
|
||||
{file = "python_telegram_bot-12.2.0-py2.py3-none-any.whl", hash = "sha256:3beee89cba3bc3217566c96199f04776dd25f541ac8992da27fd247b2d208a14"},
|
||||
|
|
|
@ -11,7 +11,7 @@ from .videochannel import VideochannelCommand
|
|||
# from .trivia import TriviaCommand
|
||||
# from .matchmaking import MatchmakingCommand
|
||||
# from .pause import PauseCommand
|
||||
# from .play import PlayCommand
|
||||
from .play import PlayCommand
|
||||
# from .playmode import PlaymodeCommand
|
||||
# from .queue import QueueCommand
|
||||
# from .skip import SkipCommand
|
||||
|
@ -39,7 +39,7 @@ available_commands = [
|
|||
# TriviaCommand,
|
||||
# MatchmakingCommand,
|
||||
# PauseCommand,
|
||||
# PlayCommand,
|
||||
PlayCommand,
|
||||
# PlaymodeCommand,
|
||||
# QueueCommand,
|
||||
# SkipCommand,
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import typing
|
||||
import pickle
|
||||
import datetime
|
||||
import base64
|
||||
import discord
|
||||
from typing import *
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import asyncify
|
||||
from royalnet.audio import YtdlDiscord
|
||||
from royalnet.bots import DiscordBot
|
||||
from royalnet.utils import *
|
||||
|
||||
|
||||
class PlayCommand(Command):
|
||||
|
@ -15,65 +13,41 @@ class PlayCommand(Command):
|
|||
|
||||
description: str = "Aggiunge un url alla coda della chat vocale."
|
||||
|
||||
syntax = "[ [guild] ] {url}"
|
||||
|
||||
@staticmethod
|
||||
async def _legacy_play_handler(bot: "DiscordBot", guild_name: typing.Optional[str], url: str):
|
||||
"""Handle a play Royalnet request. That is, add audio to a PlayMode."""
|
||||
# Find the matching guild
|
||||
if guild_name:
|
||||
guilds: typing.List[discord.Guild] = bot.client.find_guild_by_name(guild_name)
|
||||
else:
|
||||
guilds = bot.client.guilds
|
||||
if len(guilds) == 0:
|
||||
raise CommandError("Server non trovato.")
|
||||
if len(guilds) > 1:
|
||||
raise CommandError("Il nome del server è ambiguo.")
|
||||
guild = list(bot.client.guilds)[0]
|
||||
# Ensure the guild has a PlayMode before adding the file to it
|
||||
if not bot.music_data.get(guild):
|
||||
raise CommandError("Il bot non è in nessun canale vocale.")
|
||||
# Create url
|
||||
ytdl_args = {
|
||||
"format": "bestaudio/best",
|
||||
"outtmpl": f"./downloads/{datetime.datetime.now().timestamp()}_%(title)s.%(ext)s"
|
||||
}
|
||||
# Start downloading
|
||||
dfiles: typing.List[YtdlDiscord] = await asyncify(YtdlDiscord.create_from_url, url, **ytdl_args)
|
||||
await bot.add_to_music_data(dfiles, guild)
|
||||
# Create response dictionary
|
||||
response = {
|
||||
"videos": [{
|
||||
"title": dfile.info.title,
|
||||
"discord_embed_pickle": str(pickle.dumps(dfile.info.to_discord_embed()))
|
||||
} for dfile in dfiles]
|
||||
}
|
||||
return response
|
||||
|
||||
_event_name = "_legacy_play"
|
||||
|
||||
def __init__(self, interface: CommandInterface):
|
||||
super().__init__(interface)
|
||||
if interface.name == "discord":
|
||||
interface.register_herald_action(self._event_name, self._legacy_play_handler)
|
||||
syntax = "{url}"
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
guild_name, url = args.match(r"(?:\[(.+)])?\s*<?(.+)>?")
|
||||
if not (url.startswith("http://") or url.startswith("https://")):
|
||||
raise CommandError(f"Il comando [c]{self.interface.prefix}play[/c] funziona solo per riprodurre file da"
|
||||
f" un URL.\n"
|
||||
f"Se vuoi cercare un video, usa [c]{self.interface.prefix}youtube[/c] o"
|
||||
f" [c]{self.interface.prefix}soundcloud[/c]!")
|
||||
response: dict = await self.interface.call_herald_action("discord", self._event_name, {
|
||||
"guild_name": guild_name,
|
||||
"url": url
|
||||
})
|
||||
if len(response["videos"]) == 0:
|
||||
raise CommandError(f"Nessun file trovato.")
|
||||
for video in response["videos"]:
|
||||
url = args.joined()
|
||||
# if not (url.startswith("http://") or url.startswith("https://")):
|
||||
# raise CommandError(f"Il comando [c]{self.interface.prefix}play[/c] funziona solo per riprodurre file da"
|
||||
# f" un URL.\n"
|
||||
# f"Se vuoi cercare un video, come misura temporanea puoi usare "
|
||||
# f"[c]ytsearch:nomevideo[/c] o [c]scsearch:nomevideo[/c] come url.")
|
||||
if self.interface.name == "discord":
|
||||
message: discord.Message = data.message
|
||||
guild: discord.Guild = message.guild
|
||||
guild_id: Optional[int] = guild.id
|
||||
else:
|
||||
guild_id = None
|
||||
response: Dict[str, Any] = await self.interface.call_herald_event("discord", "discord_play",
|
||||
url=url, guild_id=guild_id)
|
||||
|
||||
too_long: List[Dict[str, Any]] = response["too_long"]
|
||||
if len(too_long) > 0:
|
||||
await data.reply(f"⚠ {len(too_long)} file non {'è' if len(too_long) == 1 else 'sono'}"
|
||||
f" stat{'o' if len(too_long) == 1 else 'i'} scaricat{'o' if len(too_long) == 1 else 'i'}"
|
||||
f" perchè durava{'' if len(too_long) == 1 else 'no'}"
|
||||
f" più di [c]{self.config['Play']['max_song_duration']}[/c] secondi.")
|
||||
|
||||
added: List[Dict[str, Any]] = response["added"]
|
||||
if len(added) > 0:
|
||||
reply = f"▶️ Aggiunt{'o' if len(added) == 1 else 'i'} {len(added)} file alla coda:\n"
|
||||
if self.interface.name == "discord":
|
||||
# This is one of the unsafest things ever
|
||||
embed = pickle.loads(eval(video["discord_embed_pickle"]))
|
||||
await data.message.channel.send(content="▶️ Aggiunto alla coda:", embed=embed)
|
||||
await data.reply(reply)
|
||||
for item in added:
|
||||
embed = pickle.loads(base64.b64decode(bytes(item["stringified_base64_pickled_discord_embed"],
|
||||
encoding="ascii")))
|
||||
# noinspection PyUnboundLocalVariable
|
||||
await message.channel.send(embed=embed)
|
||||
else:
|
||||
await data.reply(f"▶️ Aggiunto alla coda: [i]{video['title']}[/i]")
|
||||
reply += numberemojiformat([a["title"] for a in added])
|
||||
await data.reply(reply)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import typing
|
||||
import random
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import safeformat
|
||||
|
||||
|
||||
class SmecdsCommand(Command):
|
||||
|
@ -62,8 +61,6 @@ class SmecdsCommand(Command):
|
|||
"dello Slime God", "del salassato", "della salsa", "di Senjougahara", "di Sugar", "della Stampa",
|
||||
"della Stampante"]
|
||||
|
||||
_SMECDS = "🤔 Secondo me, è colpa {ds}."
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
ds = random.sample(self._DS_LIST, 1)[0]
|
||||
await data.reply(safeformat(self._SMECDS, ds=ds))
|
||||
await data.reply(f"🤔 Secondo me, è colpa {ds}.")
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
# Imports go here!
|
||||
from .discord_cv import DiscordCvEvent
|
||||
from .discord_summon import DiscordSummonEvent
|
||||
from .discord_play import DiscordPlayEvent
|
||||
|
||||
# Enter the commands of your Pack here!
|
||||
available_events = [
|
||||
DiscordCvEvent,
|
||||
DiscordSummonEvent,
|
||||
DiscordPlayEvent,
|
||||
]
|
||||
|
||||
# noinspection PyUnreachableCode
|
||||
|
|
61
royalpack/events/discord_play.py
Normal file
61
royalpack/events/discord_play.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
import discord
|
||||
import pickle
|
||||
import base64
|
||||
import datetime
|
||||
from typing import *
|
||||
from royalnet.commands import *
|
||||
from royalnet.serf.discord import *
|
||||
from royalnet.bard import *
|
||||
|
||||
|
||||
class DiscordPlayEvent(Event):
|
||||
name = "discord_play"
|
||||
|
||||
async def run(self,
|
||||
url: str,
|
||||
guild_id: Optional[int] = None,
|
||||
**kwargs) -> dict:
|
||||
if not isinstance(self.serf, DiscordSerf):
|
||||
raise UnsupportedError()
|
||||
client: discord.Client = self.serf.client
|
||||
if len(self.serf.voice_players) == 1:
|
||||
voice_player: VoicePlayer = self.serf.voice_players[0]
|
||||
else:
|
||||
if guild_id is None:
|
||||
# TODO: trovare un modo per riprodurre canzoni su più server da Telegram
|
||||
raise InvalidInputError("Non so in che Server riprodurre questo file...\n"
|
||||
"Invia il comando su Discord, per favore!")
|
||||
guild: discord.Guild = client.get_guild(guild_id)
|
||||
if guild is None:
|
||||
raise InvalidInputError("Impossibile trovare il Server specificato.")
|
||||
voice_player: VoicePlayer = self.serf.find_voice_player(guild)
|
||||
if voice_player is None:
|
||||
raise UserError("Il bot non è in nessun canale vocale.\n"
|
||||
"Evocalo prima con [c]summon[/c]!")
|
||||
ytds = await YtdlDiscord.from_url(url)
|
||||
added: List[YtdlDiscord] = []
|
||||
too_long: List[YtdlDiscord] = []
|
||||
if isinstance(voice_player.playing, PlayableYTDQueue):
|
||||
for ytd in ytds:
|
||||
if ytd.info.duration >= datetime.timedelta(seconds=self.config["Play"]["max_song_duration"]):
|
||||
too_long.append(ytd)
|
||||
continue
|
||||
await ytd.convert_to_pcm()
|
||||
added.append(ytd)
|
||||
voice_player.playing.contents.append(ytd)
|
||||
if not voice_player.voice_client.is_playing():
|
||||
await voice_player.start()
|
||||
else:
|
||||
raise CommandError(f"Non so come aggiungere musica a [c]{voice_player.playing.__class__.__qualname__}[/c]!")
|
||||
return {
|
||||
"added": [{
|
||||
"title": ytd.info.title,
|
||||
"stringified_base64_pickled_discord_embed": str(base64.b64encode(pickle.dumps(ytd.embed())),
|
||||
encoding="ascii")
|
||||
} for ytd in added],
|
||||
"too_long": [{
|
||||
"title": ytd.info.title,
|
||||
"stringified_base64_pickled_discord_embed": str(base64.b64encode(pickle.dumps(ytd.embed())),
|
||||
encoding="ascii")
|
||||
} for ytd in too_long]
|
||||
}
|
|
@ -9,7 +9,7 @@ class DiscordSummonEvent(Event):
|
|||
name = "discord_summon"
|
||||
|
||||
async def run(self, *,
|
||||
channel_name: Optional[str] = None,
|
||||
channel_name: str = "",
|
||||
channel_id: Optional[int] = None,
|
||||
guild_id: Optional[int] = None,
|
||||
user_id: Optional[int] = None,
|
||||
|
@ -27,11 +27,11 @@ class DiscordSummonEvent(Event):
|
|||
else:
|
||||
member = None
|
||||
# From channel id
|
||||
if channel_id:
|
||||
if channel_id is not None:
|
||||
client: discord.Client = self.serf.client
|
||||
channel = client.get_channel(channel_id)
|
||||
# Find channel
|
||||
elif channel_name is not None:
|
||||
elif channel_name != "":
|
||||
# Find accessible_to
|
||||
accessible_to = [self.serf.client.user]
|
||||
if member is not None:
|
||||
|
|
Loading…
Reference in a new issue