black -> line-length=100

This commit is contained in:
Christoph Stahl 2024-07-16 14:52:04 +02:00
parent f4e15908cc
commit 411ccdd2c9
13 changed files with 56 additions and 137 deletions

View file

@ -79,3 +79,6 @@ ignore_missing_imports = true
[tool.ruff]
line-length = 100
[tool.black]
line-length = 100

View file

@ -356,9 +356,7 @@ async def handle_request_config(data: dict[str, Any]) -> None:
:rtype: None
"""
if data["source"] in sources:
config: dict[str, Any] | list[dict[str, Any]] = await sources[
data["source"]
].get_config()
config: dict[str, Any] | list[dict[str, Any]] = await sources[data["source"]].get_config()
if isinstance(config, list):
num_chunks: int = len(config)
for current, chunk in enumerate(config):

View file

@ -76,8 +76,7 @@ class Entry:
def normalize(performers: str) -> set[str]:
return set(
filter(
lambda x: len(x) > 0
and x not in ["der", "die", "das", "alle", "und"],
lambda x: len(x) > 0 and x not in ["der", "die", "das", "alle", "und"],
re.sub(
r"[^a-zA-Z0-9\s]",
"",

View file

@ -68,9 +68,7 @@ class DateAndTimePickerWindow(customtkinter.CTkToplevel): # type: ignore
self.timepicker.pack(expand=True, fill="both")
button = customtkinter.CTkButton(
self, text="Ok", command=partial(self.insert, input_field)
)
button = customtkinter.CTkButton(self, text="Ok", command=partial(self.insert, input_field))
button.pack(expand=True, fill="x")
def insert(self, input_field: customtkinter.CTkTextbox) -> None:
@ -121,12 +119,8 @@ class OptionFrame(customtkinter.CTkScrollableFrame): # type:ignore
if value is None:
value = ""
self.string_options[name] = customtkinter.CTkTextbox(
self, wrap="none", height=1
)
self.string_options[name].grid(
column=1, row=self.number_of_options, sticky="EW"
)
self.string_options[name] = customtkinter.CTkTextbox(self, wrap="none", height=1)
self.string_options[name].grid(column=1, row=self.number_of_options, sticky="EW")
self.string_options[name].insert("0.0", value)
if callback is not None:
self.string_options[name].bind("<KeyRelease>", callback)
@ -196,22 +190,16 @@ class OptionFrame(customtkinter.CTkScrollableFrame): # type:ignore
) -> None:
self.add_option_label(description)
self.choose_options[name] = customtkinter.CTkOptionMenu(self, values=values)
self.choose_options[name].grid(
column=1, row=self.number_of_options, sticky="EW"
)
self.choose_options[name].grid(column=1, row=self.number_of_options, sticky="EW")
self.choose_options[name].set(value)
self.number_of_options += 1
def open_date_and_time_picker(
self, name: str, input_field: customtkinter.CTkTextbox
) -> None:
def open_date_and_time_picker(self, name: str, input_field: customtkinter.CTkTextbox) -> None:
if (
name not in self.date_and_time_pickers
or not self.date_and_time_pickers[name].winfo_exists()
):
self.date_and_time_pickers[name] = DateAndTimePickerWindow(
self, input_field
)
self.date_and_time_pickers[name] = DateAndTimePickerWindow(self, input_field)
else:
self.date_and_time_pickers[name].focus()
@ -307,9 +295,7 @@ class GeneralConfig(OptionFrame):
str(config["waiting_room_policy"]).lower(),
)
self.add_date_time_option("last_song", "Time of last song", config["last_song"])
self.add_string_option(
"preview_duration", "Preview Duration", config["preview_duration"]
)
self.add_string_option("preview_duration", "Preview Duration", config["preview_duration"])
def get_config(self) -> dict[str, Any]:
config = super().get_config()
@ -346,9 +332,7 @@ class SyngGui(customtkinter.CTk): # type:ignore
self.syng_server: Optional[Process] = None
self.syng_client: Optional[Process] = None
self.configfile = os.path.join(
platformdirs.user_config_dir("syng"), "config.yaml"
)
self.configfile = os.path.join(platformdirs.user_config_dir("syng"), "config.yaml")
try:
with open(self.configfile, encoding="utf8") as cfile:
@ -380,13 +364,9 @@ class SyngGui(customtkinter.CTk): # type:ignore
self.startsyng_serverbutton = customtkinter.CTkButton(
button_line, text="Start Local Server", command=self.start_syng_server
)
self.startsyng_serverbutton.pack(
side="left", expand=True, anchor="w", padx=10, pady=5
)
self.startsyng_serverbutton.pack(side="left", expand=True, anchor="w", padx=10, pady=5)
savebutton = customtkinter.CTkButton(
button_line, text="Save", command=self.save_config
)
savebutton = customtkinter.CTkButton(button_line, text="Save", command=self.save_config)
savebutton.pack(side="left", padx=10, pady=5)
# open_web_button = customtkinter.CTkButton(
@ -430,9 +410,7 @@ class SyngGui(customtkinter.CTk): # type:ignore
except (KeyError, TypeError):
source_config = {}
self.tabs[source_name] = SourceTab(
tabview.tab(source_name), source_name, source_config
)
self.tabs[source_name] = SourceTab(tabview.tab(source_name), source_name, source_config)
self.tabs[source_name].pack(ipadx=10, expand=True, fill="both")
self.update_qr()

View file

@ -1,4 +1,5 @@
"""Wraps the ``json`` module, so that own classes get encoded."""
import json
from dataclasses import asdict
from typing import Any

View file

@ -1,4 +1,5 @@
"""A async queue with synchronization."""
import asyncio
from collections import deque
from collections.abc import Callable, Iterable

View file

@ -1,4 +1,5 @@
"""Module for search results."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Optional

View file

@ -138,9 +138,7 @@ class State:
recent: list[Entry]
sid: str
client: Client
last_seen: datetime.datetime = field(
init=False, default_factory=datetime.datetime.now
)
last_seen: datetime.datetime = field(init=False, default_factory=datetime.datetime.now)
clients: dict[str, State] = {}
@ -163,9 +161,7 @@ async def send_state(state: State, sid: str) -> None:
:rtype: None
"""
safe_config = {
k: v for k, v in state.client.config.items() if k not in ["secret", "key"]
}
safe_config = {k: v for k, v in state.client.config.items() if k not in ["secret", "key"]}
await sio.emit(
"state",
@ -216,18 +212,13 @@ async def handle_waiting_room_append(sid: str, data: dict[str, Any]) -> None:
if entry is None:
await sio.emit(
"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,
)
return
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)
):
await append_to_queue(room, entry, sid)
@ -244,9 +235,7 @@ async def handle_waiting_room_append(sid: str, data: dict[str, Any]) -> None:
)
async def append_to_queue(
room: str, entry: Entry, report_to: Optional[str] = None
) -> None:
async def append_to_queue(room: str, entry: Entry, report_to: Optional[str] = None) -> None:
"""
Append a song to the queue for a given session.
@ -270,10 +259,7 @@ async def append_to_queue(
start_time = first_song.started_at
start_time = state.queue.fold(
lambda item, time: time
+ item.duration
+ state.client.config["preview_duration"]
+ 1,
lambda item, time: time + item.duration + state.client.config["preview_duration"] + 1,
start_time,
)
@ -395,15 +381,11 @@ async def handle_append(sid: str, data: dict[str, Any]) -> None:
state = clients[room]
if len(data["performer"]) > 50:
await sio.emit(
"err", {"type": "NAME_LENGTH", "name": data["performer"]}, room=sid
)
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
)
await sio.emit("err", {"type": "PROFANITY", "name": data["performer"]}, room=sid)
return
if state.client.config["waiting_room_policy"] and (
@ -462,15 +444,11 @@ async def handle_append_anyway(sid: str, data: dict[str, Any]) -> None:
state = clients[room]
if len(data["performer"]) > 50:
await sio.emit(
"err", {"type": "NAME_LENGTH", "name": data["performer"]}, room=sid
)
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
)
await sio.emit("err", {"type": "PROFANITY", "name": data["performer"]}, room=sid)
return
if state.client.config["waiting_room_policy"].lower() == "forced":
@ -582,11 +560,7 @@ async def handle_waiting_room_to_queue(sid: str, data: dict[str, Any]) -> None:
if is_admin:
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,
)
if entry is not None:
@ -718,9 +692,7 @@ async def handle_register_client(sid: str, data: dict[str, Any]) -> None:
"""
def gen_id(length: int = 4) -> str:
client_id = "".join(
[random.choice(string.ascii_letters) for _ in range(length)]
)
client_id = "".join([random.choice(string.ascii_letters) for _ in range(length)])
if client_id in clients:
client_id = gen_id(length + 1)
return client_id
@ -732,8 +704,7 @@ async def handle_register_client(sid: str, data: dict[str, Any]) -> None:
if (
"key" not in data["config"]
or hashlib.sha256(data["config"]["key"].encode()).hexdigest()
not in keys
or hashlib.sha256(data["config"]["key"].encode()).hexdigest() not in keys
):
await sio.emit(
"client-registered",
@ -743,9 +714,7 @@ async def handle_register_client(sid: str, data: dict[str, Any]) -> None:
return
room: str = (
data["config"]["room"]
if "room" in data["config"] and data["config"]["room"]
else gen_id()
data["config"]["room"] if "room" in data["config"] and data["config"]["room"] else gen_id()
)
async with sio.session(sid) as session:
session["room"] = room
@ -761,15 +730,11 @@ async def handle_register_client(sid: str, data: dict[str, Any]) -> None:
config=DEFAULT_CONFIG | data["config"],
)
await sio.enter_room(sid, room)
await sio.emit(
"client-registered", {"success": True, "room": room}, room=sid
)
await sio.emit("client-registered", {"success": True, "room": room}, room=sid)
await send_state(clients[room], sid)
else:
logger.warning("Got wrong secret for %s", room)
await sio.emit(
"client-registered", {"success": False, "room": room}, room=sid
)
await sio.emit("client-registered", {"success": False, "room": room}, room=sid)
else:
logger.info("Registerd new client %s", room)
initial_entries = [Entry(**entry) for entry in data["queue"]]
@ -860,9 +825,7 @@ async def handle_config_chunk(sid: str, data: dict[str, Any]) -> None:
return
if data["source"] not in state.client.sources:
state.client.sources[data["source"]] = available_sources[data["source"]](
data["config"]
)
state.client.sources[data["source"]] = available_sources[data["source"]](data["config"])
else:
state.client.sources[data["source"]].add_to_config(data["config"])
@ -891,9 +854,7 @@ async def handle_config(sid: str, data: dict[str, Any]) -> None:
if sid != state.sid:
return
state.client.sources[data["source"]] = available_sources[data["source"]](
data["config"]
)
state.client.sources[data["source"]] = available_sources[data["source"]](data["config"])
@sio.on("register-web")
@ -1078,17 +1039,10 @@ async def handle_search(sid: str, data: dict[str, Any]) -> None:
query = data["query"]
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 = [
search_result
for source_result in results_list
for search_result in source_result
]
results = [search_result for source_result in results_list for search_result in source_result]
await sio.emit(
"search-results",
{"results": results},
@ -1152,9 +1106,7 @@ def run_server(args: Namespace) -> None:
app["root_folder"] = args.root_folder
app.add_routes(
[web.static("/assets/", os.path.join(app["root_folder"], "assets/"))]
)
app.add_routes([web.static("/assets/", os.path.join(app["root_folder"], "assets/"))])
app.router.add_route("*", "/", root_handler)
app.router.add_route("*", "/{room}", root_handler)

View file

@ -2,6 +2,7 @@
Imports all sources, so that they add themselves to the
``available_sources`` dictionary.
"""
# pylint: disable=useless-import-alias
from typing import Any

View file

@ -1,4 +1,5 @@
"""Module for the files Source."""
import asyncio
import os
from typing import Any, Optional

View file

@ -64,13 +64,9 @@ class S3Source(FileBasedSource):
secure=(config["secure"] if "secure" in config else True),
)
self.bucket: str = config["bucket"]
self.tmp_dir: str = (
config["tmp_dir"] if "tmp_dir" in config else "/tmp/syng"
)
self.tmp_dir: str = config["tmp_dir"] if "tmp_dir" in config else "/tmp/syng"
self.index_file: Optional[str] = (
config["index_file"] if "index_file" in config else None
)
self.index_file: Optional[str] = config["index_file"] if "index_file" in config else None
self.extra_mpv_arguments = ["--scale=oversample"]
async def get_file_list(self) -> list[str]:
@ -93,8 +89,7 @@ class S3Source(FileBasedSource):
file_list = [
obj.object_name
for obj in self.minio.list_objects(self.bucket, recursive=True)
if obj.object_name is not None
and self.has_correct_extension(obj.object_name)
if obj.object_name is not None and self.has_correct_extension(obj.object_name)
]
if self.index_file is not None and not os.path.isfile(self.index_file):
with open(self.index_file, "w", encoding="utf8") as index_file_handle:
@ -140,9 +135,7 @@ class S3Source(FileBasedSource):
video_dl_path: str = os.path.join(self.tmp_dir, video_path)
os.makedirs(os.path.dirname(video_dl_path), exist_ok=True)
video_dl_task: asyncio.Task[Any] = asyncio.create_task(
asyncio.to_thread(
self.minio.fget_object, self.bucket, entry.ident, video_dl_path
)
asyncio.to_thread(self.minio.fget_object, self.bucket, entry.ident, video_dl_path)
)
audio_dl_path: Optional[str]
@ -150,9 +143,7 @@ class S3Source(FileBasedSource):
audio_dl_path = os.path.join(self.tmp_dir, audio_path)
audio_dl_task: asyncio.Task[Any] = asyncio.create_task(
asyncio.to_thread(
self.minio.fget_object, self.bucket, audio_path, audio_dl_path
)
asyncio.to_thread(self.minio.fget_object, self.bucket, audio_path, audio_dl_path)
)
else:
audio_dl_path = None

View file

@ -4,6 +4,7 @@ Abstract class for sources.
Also defines the dictionary of available sources. Each source should add itself
to this dictionary in its module.
"""
from __future__ import annotations
import asyncio

View file

@ -41,9 +41,7 @@ class YouTube:
self._infos = YouTube.__cache__[url]
else:
try:
self._infos = YoutubeDL({"quiet": True}).extract_info(
url, download=False
)
self._infos = YoutubeDL({"quiet": True}).extract_info(url, download=False)
except DownloadError:
self.length = 300
self._title = None
@ -104,7 +102,9 @@ class Search:
else:
if channel[0] == "/":
channel = channel[1:]
query_url = f"https://www.youtube.com/{channel}/search?{urlencode({'query': query, 'sp':sp})}"
query_url = (
f"https://www.youtube.com/{channel}/search?{urlencode({'query': query, 'sp':sp})}"
)
results = YoutubeDL(
{
@ -118,9 +118,7 @@ class Search:
)
self.results = []
if results is not None:
filtered_entries = filter(
lambda entry: "short" not in entry["url"], results["entries"]
)
filtered_entries = filter(lambda entry: "short" not in entry["url"], results["entries"])
for r in filtered_entries:
try:
@ -169,8 +167,7 @@ class YoutubeSource(Source):
config["start_streaming"] if "start_streaming" in config else False
)
self.formatstring = (
f"bestvideo[height<={self.max_res}]+"
f"bestaudio/best[height<={self.max_res}]"
f"bestvideo[height<={self.max_res}]+" f"bestaudio/best[height<={self.max_res}]"
)
self._yt_dlp = YoutubeDL(
params={
@ -278,15 +275,10 @@ class YoutubeSource(Source):
results: list[YouTube] = []
results_lists: list[list[YouTube]] = await asyncio.gather(
*[
asyncio.to_thread(self._channel_search, query, channel)
for channel in self.channels
],
*[asyncio.to_thread(self._channel_search, query, channel) for channel in self.channels],
asyncio.to_thread(self._yt_search, query),
)
results = [
search_result for yt_result in results_lists for search_result in yt_result
]
results = [search_result for yt_result in results_lists for search_result in yt_result]
results.sort(key=partial(_contains_index, query))