Added Waiting room by name
This commit is contained in:
parent
a1432529d3
commit
65a560c3fc
4 changed files with 86 additions and 30 deletions
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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,24 +133,27 @@ 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]:
|
||||||
yt_song = YouTube(url)
|
|
||||||
try:
|
try:
|
||||||
length = yt_song.length
|
yt_song = YouTube(url)
|
||||||
except TypeError:
|
try:
|
||||||
length = 180
|
length = yt_song.length
|
||||||
return Entry(
|
except TypeError:
|
||||||
ident=url,
|
length = 180
|
||||||
source="youtube",
|
return Entry(
|
||||||
album="YouTube",
|
ident=url,
|
||||||
duration=length,
|
source="youtube",
|
||||||
title=yt_song.title,
|
album="YouTube",
|
||||||
artist=yt_song.author,
|
duration=length,
|
||||||
performer=performer,
|
title=yt_song.title,
|
||||||
)
|
artist=yt_song.author,
|
||||||
|
performer=performer,
|
||||||
|
)
|
||||||
|
except PytubeError:
|
||||||
|
return None
|
||||||
|
|
||||||
return await asyncio.to_thread(_get_entry, performer, ident)
|
return await asyncio.to_thread(_get_entry, performer, ident)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue