Added Waiting room by name

This commit is contained in:
Christoph Stahl 2023-04-08 11:56:53 +02:00
parent a1432529d3
commit 65a560c3fc
4 changed files with 86 additions and 30 deletions

View file

@ -69,3 +69,13 @@ class Entry:
:rtype: None :rtype: None
""" """
self.__dict__.update(kwargs) self.__dict__.update(kwargs)
def shares_performer(self, other_performer: str) -> bool:
e1_split_names = set(
filter(lambda x: len(x) > 3, self.performer.split(" "))
)
e2_split_names = set(
filter(lambda x: len(x) > 3, other_performer.split(" "))
)
return len(e1_split_names.intersection(e2_split_names)) > 0

View file

@ -107,6 +107,12 @@ class Queue:
if item.uuid == uuid or str(item.uuid) == uuid: if item.uuid == uuid or str(item.uuid) == uuid:
updater(item) updater(item)
def find_by_name(self, name: str) -> Optional[Entry]:
for item in self._queue:
if item.shares_performer(name):
return item
return None
def find_by_uuid(self, uuid: UUID | str) -> Optional[Entry]: def find_by_uuid(self, uuid: UUID | str) -> Optional[Entry]:
""" """
Find an entry by its uuid and return it. Find an entry by its uuid and return it.

View file

@ -180,6 +180,10 @@ async def handle_state(sid: str) -> None:
@sio.on("waiting-room-append") @sio.on("waiting-room-append")
async def handle_waiting_room_append(sid: str, data: dict[str, Any]) -> None: async def handle_waiting_room_append(sid: str, data: dict[str, Any]) -> None:
"""
Append a song to the waiting room.
"""
async with sio.session(sid) as session: async with sio.session(sid) as session:
room = session["room"] room = session["room"]
state = clients[room] state = clients[room]
@ -187,17 +191,28 @@ async def handle_waiting_room_append(sid: str, data: dict[str, Any]) -> None:
print(data) print(data)
source_obj = state.config.sources[data["source"]] source_obj = state.config.sources[data["source"]]
entry = await source_obj.get_entry(data["performer"], data["ident"]) entry = await source_obj.get_entry(data["performer"], data["ident"])
if entry is None: if entry is None:
await sio.emit( await sio.emit(
"msg", "msg",
{"msg": f"Unable to add to the waiting room: {data['ident']}"}, {
"msg": f"Unable to add to the waiting room: {data['ident']}. Maybe try again?"
},
room=sid,
) )
return return
if ( if "uid" not in data or (
"uid" not in data (
or len(list(state.queue.find_by_uid(data["uid"]))) == 0 data["uid"] is not None
and len(list(state.queue.find_by_uid(data["uid"]))) == 0
)
or (
data["uid"] is None
and state.queue.find_by_name(data["performer"]) is None
)
): ):
await append_to_queue(room, entry, sid) await append_to_queue(room, entry, sid)
return return
@ -213,10 +228,24 @@ async def handle_waiting_room_append(sid: str, data: dict[str, Any]) -> None:
room=clients[room].sid, room=clients[room].sid,
) )
# Und jetzt iwie hinzufügen, oder direkt queuen :/
async def append_to_queue(
room: str, entry: Entry, report_to: Optional[str] = None
) -> None:
"""
Append an song to the queue for a given session.
async def append_to_queue(room, entry, report_to=None): Checks, if the computed start time is before the configured end time of the
event, and reports an error, if the end time is exceeded.
:param room: The room with the queue.
:type room: str
:param entry: The entry that contains the song.
:type entry: Entry
:param report_to: If an error occurs, who to report to.
:type report_to: Optional[str]
:rtype: None
"""
state = clients[room] state = clients[room]
first_song = state.queue.try_peek() first_song = state.queue.try_peek()
@ -294,9 +323,15 @@ async def handle_append(sid: str, data: dict[str, Any]) -> None:
state = clients[room] state = clients[room]
source_obj = state.config.sources[data["source"]] source_obj = state.config.sources[data["source"]]
entry = await source_obj.get_entry(data["performer"], data["ident"]) entry = await source_obj.get_entry(data["performer"], data["ident"])
if entry is None: if entry is None:
await sio.emit("msg", {"msg": f"Unable to append {data['ident']}"}) await sio.emit(
"msg",
{"msg": f"Unable to append {data['ident']}. Maybe try again?"},
room=sid,
)
return return
entry.uid = data["uid"] if "uid" in data else None entry.uid = data["uid"] if "uid" in data else None
@ -367,12 +402,15 @@ async def handle_get_first(sid: str) -> None:
await sio.emit("play", current, room=sid) await sio.emit("play", current, room=sid)
async def add_uid_from_waiting_room(uid, room) -> None: async def add_song_from_waiting_room(old_entry: Entry, room: str) -> None:
state = clients[room] state = clients[room]
first_entry_for_uid = None first_entry_for_uid = None
for wr_entry in state.waiting_room: for wr_entry in state.waiting_room:
if wr_entry.uid == uid: if wr_entry.uid == old_entry.uid or (
wr_entry.uid == None
and wr_entry.shares_performer(old_entry.performer)
):
first_entry_for_uid = wr_entry first_entry_for_uid = wr_entry
break break
@ -381,12 +419,12 @@ async def add_uid_from_waiting_room(uid, room) -> None:
state.waiting_room.remove(first_entry_for_uid) state.waiting_room.remove(first_entry_for_uid)
async def discard_first(room) -> Entry: async def discard_first(room: str) -> Entry:
state = clients[room] state = clients[room]
old_entry = await state.queue.popleft() old_entry = await state.queue.popleft()
await add_uid_from_waiting_room(old_entry.uid, room) await add_song_from_waiting_room(old_entry, room)
state.recent.append(old_entry) state.recent.append(old_entry)
state.last_seen = datetime.datetime.now() state.last_seen = datetime.datetime.now()
@ -776,7 +814,7 @@ async def handle_skip(sid: str, data: dict[str, Any]) -> None:
if entry is not None: if entry is not None:
logger.info("Skipping %s", entry) logger.info("Skipping %s", entry)
await add_uid_from_waiting_room(entry.uid, room) await add_song_from_waiting_room(entry, room)
await state.queue.remove(entry) await state.queue.remove(entry)
@ -786,8 +824,6 @@ async def handle_skip(sid: str, data: dict[str, Any]) -> None:
first_entry_index = idx first_entry_index = idx
break break
print(first_entry_index)
if first_entry_index is not None: if first_entry_index is not None:
logger.info( logger.info(
"Deleting %s from waiting room", "Deleting %s from waiting room",

View file

@ -19,6 +19,7 @@ from pytube import Search
from pytube import Stream from pytube import Stream
from pytube import StreamQuery from pytube import StreamQuery
from pytube import YouTube from pytube import YouTube
from pytube.exceptions import PytubeError
try: try:
from yt_dlp import YoutubeDL from yt_dlp import YoutubeDL
@ -120,7 +121,7 @@ class YoutubeSource(Source):
else: else:
await super().play(entry) await super().play(entry)
async def get_entry(self, performer: str, ident: str) -> Entry: async def get_entry(self, performer: str, ident: str) -> Optional[Entry]:
""" """
Create an :py:class:`syng.entry.Entry` for the identifier. Create an :py:class:`syng.entry.Entry` for the identifier.
@ -132,10 +133,11 @@ class YoutubeSource(Source):
:param ident: A url to a YouTube video. :param ident: A url to a YouTube video.
:type ident: str :type ident: str
:return: An entry with the data. :return: An entry with the data.
:rtype: Entry :rtype: Optional[Entry]
""" """
def _get_entry(performer: str, url: str) -> Entry: def _get_entry(performer: str, url: str) -> Optional[Entry]:
try:
yt_song = YouTube(url) yt_song = YouTube(url)
try: try:
length = yt_song.length length = yt_song.length
@ -150,6 +152,8 @@ class YoutubeSource(Source):
artist=yt_song.author, artist=yt_song.author,
performer=performer, performer=performer,
) )
except PytubeError:
return None
return await asyncio.to_thread(_get_entry, performer, ident) return await asyncio.to_thread(_get_entry, performer, ident)