Implemented a profanity checker for performer names
This commit is contained in:
parent
60b0fd42c2
commit
d2d316078b
6 changed files with 47 additions and 65 deletions
|
@ -34,12 +34,14 @@ packaging = {version = "^23.2", optional = true}
|
||||||
types-pyyaml = {version = "^6.0.12.12", optional = true}
|
types-pyyaml = {version = "^6.0.12.12", optional = true}
|
||||||
types-pillow = {version = "^10.1.0.2", optional = true}
|
types-pillow = {version = "^10.1.0.2", optional = true}
|
||||||
mypy = {version = "^1.10.0", optional = true}
|
mypy = {version = "^1.10.0", optional = true}
|
||||||
|
alt-profanity-check = {version = "^1.4.1", optional = true}
|
||||||
|
|
||||||
[tool.poetry.extras]
|
[tool.poetry.extras]
|
||||||
client = ["minio", "mutagen", "pillow", "customtkinter", "qrcode",
|
client = ["minio", "mutagen", "pillow", "customtkinter", "qrcode",
|
||||||
"pymediainfo", "pyyaml", "tkcalendar", "tktimepicker", "platformdirs",
|
"pymediainfo", "pyyaml", "tkcalendar", "tktimepicker", "platformdirs",
|
||||||
"packaging"]
|
"packaging"]
|
||||||
dev = ["types-pillow", "types-pillow", "mypy"]
|
dev = ["types-pillow", "types-pillow", "mypy"]
|
||||||
|
server = ["alt-profanity-check"]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
|
|
|
@ -32,6 +32,7 @@ from typing import Optional
|
||||||
|
|
||||||
import socketio
|
import socketio
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
|
from profanity_check import predict
|
||||||
|
|
||||||
from . import jsonencoder
|
from . import jsonencoder
|
||||||
from .entry import Entry
|
from .entry import Entry
|
||||||
|
@ -136,9 +137,7 @@ class State:
|
||||||
recent: list[Entry]
|
recent: list[Entry]
|
||||||
sid: str
|
sid: str
|
||||||
client: Client
|
client: Client
|
||||||
last_seen: datetime.datetime = field(
|
last_seen: datetime.datetime = field(init=False, default_factory=datetime.datetime.now)
|
||||||
init=False, default_factory=datetime.datetime.now
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
clients: dict[str, State] = {}
|
clients: dict[str, State] = {}
|
||||||
|
@ -161,9 +160,7 @@ async def send_state(state: State, sid: str) -> None:
|
||||||
:rtype: None
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
safe_config = {
|
safe_config = {k: v for k, v in state.client.config.items() if k not in ["secret", "key"]}
|
||||||
k: v for k, v in state.client.config.items() if k not in ["secret", "key"]
|
|
||||||
}
|
|
||||||
|
|
||||||
await sio.emit(
|
await sio.emit(
|
||||||
"state",
|
"state",
|
||||||
|
@ -214,18 +211,13 @@ async def handle_waiting_room_append(sid: str, data: dict[str, Any]) -> None:
|
||||||
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']}. Maybe try again?"},
|
||||||
"msg": f"Unable to add to the waiting room: {data['ident']}. Maybe try again?"
|
|
||||||
},
|
|
||||||
room=sid,
|
room=sid,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if "uid" not in data or (
|
if "uid" not in data or (
|
||||||
(
|
(data["uid"] is not None and 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)
|
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)
|
||||||
|
@ -242,9 +234,7 @@ async def handle_waiting_room_append(sid: str, data: dict[str, Any]) -> None:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def append_to_queue(
|
async def append_to_queue(room: str, entry: Entry, report_to: Optional[str] = None) -> None:
|
||||||
room: str, entry: Entry, report_to: Optional[str] = None
|
|
||||||
) -> None:
|
|
||||||
"""
|
"""
|
||||||
Append a song to the queue for a given session.
|
Append a song to the queue for a given session.
|
||||||
|
|
||||||
|
@ -268,10 +258,7 @@ async def append_to_queue(
|
||||||
start_time = first_song.started_at
|
start_time = first_song.started_at
|
||||||
|
|
||||||
start_time = state.queue.fold(
|
start_time = state.queue.fold(
|
||||||
lambda item, time: time
|
lambda item, time: time + item.duration + state.client.config["preview_duration"] + 1,
|
||||||
+ item.duration
|
|
||||||
+ state.client.config["preview_duration"]
|
|
||||||
+ 1,
|
|
||||||
start_time,
|
start_time,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -392,6 +379,14 @@ async def handle_append(sid: str, data: dict[str, Any]) -> None:
|
||||||
room = session["room"]
|
room = session["room"]
|
||||||
state = clients[room]
|
state = clients[room]
|
||||||
|
|
||||||
|
if len(data["performer"]) > 50:
|
||||||
|
await sio.emit("err", {"type": "NAME_LENGTH", "name": data["performer"]}, room=sid)
|
||||||
|
return
|
||||||
|
|
||||||
|
if predict([data["performer"]]) == [1]:
|
||||||
|
await sio.emit("err", {"type": "PROFANITY", "name": data["performer"]}, room=sid)
|
||||||
|
return
|
||||||
|
|
||||||
if state.client.config["waiting_room_policy"] and (
|
if state.client.config["waiting_room_policy"] and (
|
||||||
state.client.config["waiting_room_policy"].lower() == "forced"
|
state.client.config["waiting_room_policy"].lower() == "forced"
|
||||||
or state.client.config["waiting_room_policy"].lower() == "optional"
|
or state.client.config["waiting_room_policy"].lower() == "optional"
|
||||||
|
@ -447,6 +442,14 @@ async def handle_append_anyway(sid: str, data: dict[str, Any]) -> None:
|
||||||
room = session["room"]
|
room = session["room"]
|
||||||
state = clients[room]
|
state = clients[room]
|
||||||
|
|
||||||
|
if len(data["performer"]) > 50:
|
||||||
|
await sio.emit("err", {"type": "NAME_LENGTH", "name": data["performer"]}, room=sid)
|
||||||
|
return
|
||||||
|
|
||||||
|
if predict([data["performer"]]) == [1]:
|
||||||
|
await sio.emit("err", {"type": "PROFANITY", "name": data["performer"]}, room=sid)
|
||||||
|
return
|
||||||
|
|
||||||
if state.client.config["waiting_room_policy"].lower() == "forced":
|
if state.client.config["waiting_room_policy"].lower() == "forced":
|
||||||
await sio.emit(
|
await sio.emit(
|
||||||
"err",
|
"err",
|
||||||
|
@ -556,11 +559,7 @@ async def handle_waiting_room_to_queue(sid: str, data: dict[str, Any]) -> None:
|
||||||
|
|
||||||
if is_admin:
|
if is_admin:
|
||||||
entry = next(
|
entry = next(
|
||||||
(
|
(wr_entry for wr_entry in state.waiting_room if str(wr_entry.uuid) == data["uuid"]),
|
||||||
wr_entry
|
|
||||||
for wr_entry in state.waiting_room
|
|
||||||
if str(wr_entry.uuid) == data["uuid"]
|
|
||||||
),
|
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
if entry is not None:
|
if entry is not None:
|
||||||
|
@ -692,9 +691,7 @@ async def handle_register_client(sid: str, data: dict[str, Any]) -> None:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def gen_id(length: int = 4) -> str:
|
def gen_id(length: int = 4) -> str:
|
||||||
client_id = "".join(
|
client_id = "".join([random.choice(string.ascii_letters) for _ in range(length)])
|
||||||
[random.choice(string.ascii_letters) for _ in range(length)]
|
|
||||||
)
|
|
||||||
if client_id in clients:
|
if client_id in clients:
|
||||||
client_id = gen_id(length + 1)
|
client_id = gen_id(length + 1)
|
||||||
return client_id
|
return client_id
|
||||||
|
@ -706,8 +703,7 @@ async def handle_register_client(sid: str, data: dict[str, Any]) -> None:
|
||||||
|
|
||||||
if (
|
if (
|
||||||
"key" not in data["config"]
|
"key" not in data["config"]
|
||||||
or hashlib.sha256(data["config"]["key"].encode()).hexdigest()
|
or hashlib.sha256(data["config"]["key"].encode()).hexdigest() not in keys
|
||||||
not in keys
|
|
||||||
):
|
):
|
||||||
await sio.emit(
|
await sio.emit(
|
||||||
"client-registered",
|
"client-registered",
|
||||||
|
@ -717,9 +713,7 @@ async def handle_register_client(sid: str, data: dict[str, Any]) -> None:
|
||||||
return
|
return
|
||||||
|
|
||||||
room: str = (
|
room: str = (
|
||||||
data["config"]["room"]
|
data["config"]["room"] if "room" in data["config"] and data["config"]["room"] else gen_id()
|
||||||
if "room" in data["config"] and data["config"]["room"]
|
|
||||||
else gen_id()
|
|
||||||
)
|
)
|
||||||
async with sio.session(sid) as session:
|
async with sio.session(sid) as session:
|
||||||
session["room"] = room
|
session["room"] = room
|
||||||
|
@ -735,15 +729,11 @@ async def handle_register_client(sid: str, data: dict[str, Any]) -> None:
|
||||||
config=DEFAULT_CONFIG | data["config"],
|
config=DEFAULT_CONFIG | data["config"],
|
||||||
)
|
)
|
||||||
await sio.enter_room(sid, room)
|
await sio.enter_room(sid, room)
|
||||||
await sio.emit(
|
await sio.emit("client-registered", {"success": True, "room": room}, room=sid)
|
||||||
"client-registered", {"success": True, "room": room}, room=sid
|
|
||||||
)
|
|
||||||
await send_state(clients[room], sid)
|
await send_state(clients[room], sid)
|
||||||
else:
|
else:
|
||||||
logger.warning("Got wrong secret for %s", room)
|
logger.warning("Got wrong secret for %s", room)
|
||||||
await sio.emit(
|
await sio.emit("client-registered", {"success": False, "room": room}, room=sid)
|
||||||
"client-registered", {"success": False, "room": room}, room=sid
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
logger.info("Registerd new client %s", room)
|
logger.info("Registerd new client %s", room)
|
||||||
initial_entries = [Entry(**entry) for entry in data["queue"]]
|
initial_entries = [Entry(**entry) for entry in data["queue"]]
|
||||||
|
@ -834,9 +824,7 @@ async def handle_config_chunk(sid: str, data: dict[str, Any]) -> None:
|
||||||
return
|
return
|
||||||
|
|
||||||
if data["source"] not in state.client.sources:
|
if data["source"] not in state.client.sources:
|
||||||
state.client.sources[data["source"]] = available_sources[data["source"]](
|
state.client.sources[data["source"]] = available_sources[data["source"]](data["config"])
|
||||||
data["config"]
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
state.client.sources[data["source"]].add_to_config(data["config"])
|
state.client.sources[data["source"]].add_to_config(data["config"])
|
||||||
|
|
||||||
|
@ -865,9 +853,7 @@ async def handle_config(sid: str, data: dict[str, Any]) -> None:
|
||||||
if sid != state.sid:
|
if sid != state.sid:
|
||||||
return
|
return
|
||||||
|
|
||||||
state.client.sources[data["source"]] = available_sources[data["source"]](
|
state.client.sources[data["source"]] = available_sources[data["source"]](data["config"])
|
||||||
data["config"]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@sio.on("register-web")
|
@sio.on("register-web")
|
||||||
|
@ -1052,17 +1038,10 @@ async def handle_search(sid: str, data: dict[str, Any]) -> None:
|
||||||
|
|
||||||
query = data["query"]
|
query = data["query"]
|
||||||
results_list = await asyncio.gather(
|
results_list = await asyncio.gather(
|
||||||
*[
|
*[state.client.sources[source].search(query) for source in state.client.sources_prio]
|
||||||
state.client.sources[source].search(query)
|
|
||||||
for source in state.client.sources_prio
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
results = [
|
results = [search_result for source_result in results_list for search_result in source_result]
|
||||||
search_result
|
|
||||||
for source_result in results_list
|
|
||||||
for search_result in source_result
|
|
||||||
]
|
|
||||||
await sio.emit(
|
await sio.emit(
|
||||||
"search-results",
|
"search-results",
|
||||||
{"results": results},
|
{"results": results},
|
||||||
|
@ -1143,9 +1122,7 @@ def main() -> None:
|
||||||
|
|
||||||
app["root_folder"] = args.root_folder
|
app["root_folder"] = args.root_folder
|
||||||
|
|
||||||
app.add_routes(
|
app.add_routes([web.static("/assets/", os.path.join(app["root_folder"], "assets/"))])
|
||||||
[web.static("/assets/", os.path.join(app["root_folder"], "assets/"))]
|
|
||||||
)
|
|
||||||
|
|
||||||
app.router.add_route("*", "/", root_handler)
|
app.router.add_route("*", "/", root_handler)
|
||||||
app.router.add_route("*", "/{room}", root_handler)
|
app.router.add_route("*", "/{room}", root_handler)
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -5,8 +5,8 @@
|
||||||
<link rel="icon" href="/favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Syng Rocks!</title>
|
<title>Syng Rocks!</title>
|
||||||
<script type="module" crossorigin src="/assets/index.20e81f9f.js"></script>
|
<script type="module" crossorigin src="/assets/index.01568ada.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/index.b030f504.css">
|
<link rel="stylesheet" href="/assets/index.bc7dfd5a.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|
3
typings/profanity_check.pyi
Normal file
3
typings/profanity_check.pyi
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
|
def predict(strings: list[str]) -> list[Literal[0] | Literal[1]]: ...
|
Loading…
Add table
Reference in a new issue