1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-27 13:34:28 +00:00

Add lazy music commands

This commit is contained in:
Steffo 2020-03-29 21:19:58 +02:00
parent 87f8c84eba
commit 9e129e7ad0
12 changed files with 313 additions and 2 deletions

View file

@ -40,6 +40,14 @@ from .diarioshuffle import DiarioshuffleCommand
from .funkwhaleplaylist import FunkwhaleplaylistCommand from .funkwhaleplaylist import FunkwhaleplaylistCommand
from .voicestatus import VoicestatusCommand from .voicestatus import VoicestatusCommand
from .playmode import PlaymodeCommand from .playmode import PlaymodeCommand
from .lazyplay import LazyplayCommand
from .lazyfunkwhale import LazyfunkwhaleCommand
from .lazyfunkwhaleplaylist import LazyfunkwhaleplaylistCommand
from .lazygooglevideo import LazygooglevideoCommand
from .lazypeertube import LazypeertubeCommand
from .lazysoundcloud import LazysoundcloudCommand
from .lazyyahoovideo import LazyyahoovideoCommand
from .lazyyoutube import LazyyoutubeCommand
# Enter the commands of your Pack here! # Enter the commands of your Pack here!
available_commands = [ available_commands = [
@ -84,6 +92,14 @@ available_commands = [
FunkwhaleplaylistCommand, FunkwhaleplaylistCommand,
VoicestatusCommand, VoicestatusCommand,
PlaymodeCommand, PlaymodeCommand,
LazyplayCommand,
LazyfunkwhaleCommand,
LazyfunkwhaleplaylistCommand,
LazygooglevideoCommand,
LazypeertubeCommand,
LazysoundcloudCommand,
LazyyahoovideoCommand,
LazyyoutubeCommand,
] ]
# Don't change this, it should automatically generate __all__ # Don't change this, it should automatically generate __all__

View file

@ -0,0 +1,27 @@
from .lazyplay import LazyplayCommand
from royalnet.commands import *
import aiohttp
import urllib.parse
class LazyfunkwhaleCommand(LazyplayCommand):
name: str = "lazyfunkwhale"
aliases = ["lazyfuckwhale", "lfw", "lazyroyalwhale", "lrw"]
description: str = "Cerca una canzone su RoyalWhale e aggiungila (lazy) alla coda della chat vocale."
syntax = "{ricerca}"
def get_embed_color(self):
return 0x009FE3
async def get_urls(self, args):
search = urllib.parse.quote(args.joined(require_at_least=1))
async with aiohttp.ClientSession() as session:
async with session.get(self.config["Funkwhale"]["instance_url"] +
f"/api/v1/search?query={search}") as response:
j = await response.json()
if len(j["tracks"]) < 1:
raise UserError("Nessun file audio trovato con il nome richiesto.")
return [f'{self.config["Funkwhale"]["instance_url"]}{j["tracks"][0]["listen_url"]}']

View file

@ -0,0 +1,32 @@
from .lazyplay import LazyplayCommand
from royalnet.commands import *
import aiohttp
import urllib.parse
class LazyfunkwhaleplaylistCommand(LazyplayCommand):
name: str = "lazyfunkwhaleplaylist"
aliases = ["lfwp", "lfwplaylist", "lazyfunkwhalep"]
description: str = "Cerca una playlist su RoyalWhale e aggiungila (lazy) alla coda della chat vocale."
syntax = "{ricerca}"
def get_embed_color(self):
return 0x009FE3
async def get_urls(self, args):
search = urllib.parse.quote(args.joined(require_at_least=1))
async with aiohttp.ClientSession() as session:
async with session.get(self.config["Funkwhale"]["instance_url"] +
f"/api/v1/playlists/?q={search}&ordering=-creation_date&playable=true") as response:
j = await response.json()
if len(j["results"]) < 1:
raise UserError("Nessuna playlist trovata con il nome richiesto.")
playlist = j["results"][0]
playlist_id = playlist["id"]
async with session.get(self.config["Funkwhale"]["instance_url"] +
f"/api/v1/playlists/{playlist_id}/tracks") as response:
j = await response.json()
return list(map(lambda t: f'{self.config["Funkwhale"]["instance_url"]}{t["track"]["listen_url"]}', j["results"]))

View file

@ -0,0 +1,16 @@
from .lazyplay import LazyplayCommand
class LazygooglevideoCommand(LazyplayCommand):
name: str = "lazygooglevideo"
aliases = ["lgv"]
description: str = "Cerca un video su Google Video e lo aggiunge (lazy) alla coda della chat vocale."
syntax = "{ricerca}"
async def get_urls(self, args):
return [f"gvsearch:{args.joined()}"]
# Too bad gvsearch: always finds nothing.

View file

@ -0,0 +1,24 @@
from .lazyplay import LazyplayCommand
from royalnet.commands import *
import aiohttp
import urllib.parse
class LazypeertubeCommand(LazyplayCommand):
name: str = "lazypeertube"
aliases = ["lpt", "lazyroyaltube", "lrt"]
description: str = "Cerca un video su RoyalTube e lo aggiunge (lazy) alla coda della chat vocale."
syntax = "{ricerca}"
async def get_urls(self, args):
search = urllib.parse.quote(args.joined(require_at_least=1))
async with aiohttp.ClientSession() as session:
async with session.get(self.config["Peertube"]["instance_url"] +
f"/api/v1/search/videos?search={search}") as response:
j = await response.json()
if j["total"] < 1:
raise InvalidInputError("Nessun video trovato.")
return [f'{self.config["Peertube"]["instance_url"]}/videos/watch/{j["data"][0]["uuid"]}']

View file

@ -0,0 +1,62 @@
import discord
import asyncio as aio
from typing import *
from royalnet.commands import *
from royalnet.backpack.tables import User, Discord
class LazyplayCommand(Command):
name: str = "lazyplay"
aliases = ["lp"]
description: str = "Aggiunge un url alla coda della chat vocale, ma lo scarica solo quando sta per essere" \
" riprodotto."
syntax = "{url}"
async def get_urls(self, args: CommandArgs):
url = args.joined(require_at_least=1)
if not (url.startswith("http://") or url.startswith("https://")):
raise InvalidInputError(f"L'URL specificato non inizia con il nome di un protocollo supportato"
f" ([c]http://[/c] o [c]https://[/c]).")
return [url]
def get_embed_color(self) -> Optional[int]:
return None
async def run(self, args: CommandArgs, data: CommandData) -> None:
if self.interface.name == "discord":
message: discord.Message = data.message
guild: discord.Guild = message.guild
if guild is None:
guild_id = None
else:
guild_id: Optional[int] = guild.id
else:
guild_id = None
user: User = await data.get_author()
user_str = None
if user is not None:
try:
user_discord: Discord = user.discord[0]
except (AttributeError, IndexError):
user_str = str(user)
else:
user_str = str(f"<@{user_discord.discord_id}>")
urls = await self.get_urls(args)
play_task: aio.Task = self.loop.create_task(
self.interface.call_herald_event("discord", "discord_lazy_play",
urls=urls,
guild_id=guild_id,
user=user_str,
force_color=self.get_embed_color())
)
await data.reply("⌛ Attendi un attimo...")
await play_task

View file

@ -0,0 +1,14 @@
from .lazyplay import LazyplayCommand
class LazysoundcloudCommand(LazyplayCommand):
name: str = "lazysoundcloud"
aliases = ["lsc"]
description: str = "Cerca un video su SoundCloud e lo aggiunge (lazy) alla coda della chat vocale."
syntax = "{ricerca}"
async def get_urls(self, args):
return [f"scsearch:{args.joined()}"]

View file

@ -0,0 +1,16 @@
from .lazyplay import LazyplayCommand
class LazyyahoovideoCommand(LazyplayCommand):
name: str = "lazyyahoovideo"
aliases = ["lyv"]
description: str = "Cerca un video su Yahoo Video e lo aggiunge (lazy) alla coda della chat vocale."
syntax = "{ricerca}"
async def get_urls(self, args):
return [f"yvsearch:{args.joined()}"]
# Too bad yvsearch: always finds nothing.

View file

@ -0,0 +1,14 @@
from .lazyplay import LazyplayCommand
class LazyyoutubeCommand(LazyplayCommand):
name: str = "lazyyoutube"
aliases = ["lyt"]
description: str = "Cerca un video su YouTube e lo aggiunge (lazy) alla coda della chat vocale."
syntax = "{ricerca}"
async def get_urls(self, args):
return [f"ytsearch:{args.joined()}"]

View file

@ -13,7 +13,7 @@ class PeertubeCommand(PlayCommand):
syntax = "{ricerca}" syntax = "{ricerca}"
async def get_url(self, args): async def get_urls(self, args):
search = urllib.parse.quote(args.joined(require_at_least=1)) search = urllib.parse.quote(args.joined(require_at_least=1))
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.get(self.config["Peertube"]["instance_url"] + async with session.get(self.config["Peertube"]["instance_url"] +
@ -21,4 +21,4 @@ class PeertubeCommand(PlayCommand):
j = await response.json() j = await response.json()
if j["total"] < 1: if j["total"] < 1:
raise InvalidInputError("Nessun video trovato.") raise InvalidInputError("Nessun video trovato.")
return f'{self.config["Peertube"]["instance_url"]}/videos/watch/{j["data"][0]["uuid"]}' return [f'{self.config["Peertube"]["instance_url"]}/videos/watch/{j["data"][0]["uuid"]}']

View file

@ -6,6 +6,7 @@ from .discord_skip import DiscordSkipEvent
from .discord_queue import DiscordQueueEvent from .discord_queue import DiscordQueueEvent
from .discord_pause import DiscordPauseEvent from .discord_pause import DiscordPauseEvent
from .discord_playable import DiscordPlaymodeEvent from .discord_playable import DiscordPlaymodeEvent
from .discord_lazy_play import DiscordLazyPlayEvent
# Enter the commands of your Pack here! # Enter the commands of your Pack here!
available_events = [ available_events = [
@ -16,6 +17,7 @@ available_events = [
DiscordQueueEvent, DiscordQueueEvent,
DiscordPauseEvent, DiscordPauseEvent,
DiscordPlaymodeEvent, DiscordPlaymodeEvent,
DiscordLazyPlayEvent,
] ]
# Don't change this, it should automatically generate __all__ # Don't change this, it should automatically generate __all__

View file

@ -0,0 +1,88 @@
import datetime
from typing import *
import discord
import royalnet.commands as rc
import royalnet.serf.discord as rsd
import royalnet.bard.discord as rbd
from ..utils import RoyalQueue
class DiscordLazyPlayEvent(rc.Event):
name = "discord_lazy_play"
async def run(self,
urls: List[str],
guild_id: Optional[int] = None,
user: Optional[str] = None,
force_color: Optional[int] = None,
**kwargs) -> dict:
if not isinstance(self.serf, rsd.DiscordSerf):
raise rc.UnsupportedError()
serf: rsd.DiscordSerf = self.serf
client: discord.Client = self.serf.client
guild: discord.Guild = client.get_guild(guild_id) if guild_id is not None else None
candidate_players: List[rsd.VoicePlayer] = serf.find_voice_players(guild)
if len(candidate_players) == 0:
raise rc.UserError("Il bot non è in nessun canale vocale.\n"
"Evocalo prima con [c]summon[/c]!")
elif len(candidate_players) == 1:
voice_player = candidate_players[0]
else:
raise rc.CommandError("Non so in che Server riprodurre questo file...\n"
"Invia il comando su Discord, per favore!")
added: List[rbd.YtdlDiscord] = []
too_long: List[rbd.YtdlDiscord] = []
for url in urls:
ytds = await rbd.YtdlDiscord.from_url(url)
if isinstance(voice_player.playing, RoyalQueue):
for index, ytd in enumerate(ytds):
if ytd.info.duration >= datetime.timedelta(seconds=self.config["Play"]["max_song_duration"]):
too_long.append(ytd)
continue
added.append(ytd)
voice_player.playing.contents.append(ytd)
if not voice_player.voice_client.is_playing():
await voice_player.start()
else:
raise rc.CommandError(f"Non so come aggiungere musica a [c]{voice_player.playing.__class__.__qualname__}[/c]!")
main_channel: discord.TextChannel = client.get_channel(self.config["Discord"]["main_channel_id"])
if len(added) > 0:
if user:
await main_channel.send(rsd.escape(f"▶️ {user} ha aggiunto {len(added)} file _(lazy)_ alla coda:"))
else:
await main_channel.send(rsd.escape(f"▶️ Aggiunt{'o' if len(added) == 1 else 'i'} {len(added)} file "
f"_(lazy)_ alla coda:"))
for ytd in added:
embed: discord.Embed = ytd.embed()
if force_color:
embed._colour = discord.Colour(force_color)
await main_channel.send(embed=embed)
if len(too_long) > 0:
if user:
await main_channel.send(rsd.escape(
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."
))
if len(added) + len(too_long) == 0:
raise rc.InvalidInputError("Non è stato aggiunto nessun file alla coda.")
return {
"added": [{
"title": ytd.info.title,
} for ytd in added],
"too_long": [{
"title": ytd.info.title,
} for ytd in too_long]
}