chore: konfiguracja ruff i poprawki wskazane przez lintera
Ruff jako linter i formatter, konfiguracja w pyproject.toml: - reguły E, W, F, I, N, UP, B, C4, SIM, TID, BLE, RUF - extend-immutable-calls dla fastapi.Depends, File i Query - wstrzykiwanie zależności opiera się na wywołaniach w wartościach domyślnych argumentów, więc bugbear B008 zgłaszał tam 66 fałszywych trafień - zakaz importów względnych, aby ścieżki w pakiecie czytało się jednoznacznie - katalog frontend wyłączony z analizy Poprawki, które wskazał linter: - Awaitable, Callable i AsyncIterator importowane z collections.abc zamiast z typing - zbędny argument trybu w open(path, "r") - contextlib.suppress zamiast try/except/pass przy anulowaniu zadania - zdjęte dwie niepotrzebne dyrektywy noqa - pięć linii przekraczających 100 znaków zawiniętych Całość przepuszczona przez ruff format. Do .gitignore dochodzi .ruff_cache/. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ccfb0d2e34
commit
2a961e1a8a
12 files changed
+80
-30
No files matched your search
@@ -21,7 +21,9 @@ class TrackFactory:
|
||||
self._probe = probe or MediaProbe()
|
||||
self._ytdl = yt_dlp.YoutubeDL(YtdlOptions.EXTRACTOR)
|
||||
|
||||
async def resolve(self, query: str, *, loop: asyncio.AbstractEventLoop | None = None) -> YTDLSource:
|
||||
async def resolve(
|
||||
self, query: str, *, loop: asyncio.AbstractEventLoop | None = None
|
||||
) -> YTDLSource:
|
||||
"""Rozpoznaje, czy zapytanie wskazuje wgrany plik, czy zasób sieciowy."""
|
||||
if not query.startswith("http") and self._uploads.exists(query):
|
||||
return await self.from_file(self._uploads.resolve(query))
|
||||
|
||||
@@ -36,9 +36,7 @@ class ZyrarBot(commands.Bot):
|
||||
if self.player is None:
|
||||
raise RuntimeError("MusicPlayer musi zostać przypisany przed startem bota")
|
||||
|
||||
await self.add_cog(
|
||||
MusicCog(self, self.player, self.tracks, self.uploads, self.settings)
|
||||
)
|
||||
await self.add_cog(MusicCog(self, self.player, self.tracks, self.uploads, self.settings))
|
||||
|
||||
if self.settings.guild_id:
|
||||
guild = discord.Object(id=self.settings.guild_id)
|
||||
|
||||
@@ -74,10 +74,10 @@ class MusicCog(commands.Cog, name="MusicBot"):
|
||||
return False
|
||||
return True
|
||||
|
||||
async def _enqueue_and_reply(self, interaction: discord.Interaction, track, *, prefix: str = "") -> None:
|
||||
result = await self.player.enqueue(
|
||||
interaction.guild.id, track, channel=interaction.channel
|
||||
)
|
||||
async def _enqueue_and_reply(
|
||||
self, interaction: discord.Interaction, track, *, prefix: str = ""
|
||||
) -> None:
|
||||
result = await self.player.enqueue(interaction.guild.id, track, channel=interaction.channel)
|
||||
title = discord.utils.escape_markdown(track.title or "Nieznany tytuł")
|
||||
action = "Dodano do kolejki" if result["status"] == "queued" else "Teraz odtwarzane"
|
||||
await interaction.followup.send(f"{action}{prefix}: {title}")
|
||||
@@ -161,7 +161,9 @@ class MusicCog(commands.Cog, name="MusicBot"):
|
||||
for entry in matches[:AUTOCOMPLETE_LIMIT]
|
||||
]
|
||||
|
||||
@app_commands.command(name="history", description="Pokaż historię ostatnio odtwarzanych utworów")
|
||||
@app_commands.command(
|
||||
name="history", description="Pokaż historię ostatnio odtwarzanych utworów"
|
||||
)
|
||||
async def show_history(self, interaction: discord.Interaction) -> None:
|
||||
entries = self.player.history(interaction.guild.id)
|
||||
if not entries:
|
||||
@@ -263,9 +265,7 @@ class MusicCog(commands.Cog, name="MusicBot"):
|
||||
voice_client.stop()
|
||||
self.player.clear(guild_id)
|
||||
await self.player.trigger_state_change()
|
||||
await interaction.response.send_message(
|
||||
"Zatrzymano odtwarzanie i wyczyszczono kolejkę."
|
||||
)
|
||||
await interaction.response.send_message("Zatrzymano odtwarzanie i wyczyszczono kolejkę.")
|
||||
|
||||
@app_commands.command(name="volume", description="Zmień głośność odtwarzacza")
|
||||
@app_commands.describe(volume="Poziom głośności (1-100)")
|
||||
@@ -299,7 +299,9 @@ class MusicCog(commands.Cog, name="MusicBot"):
|
||||
@app_commands.command(name="leave", description="Odłącz bota od kanału głosowego")
|
||||
async def leave(self, interaction: discord.Interaction) -> None:
|
||||
if interaction.guild.voice_client is None:
|
||||
await interaction.response.send_message("Nie jestem na kanale głosowym.", ephemeral=True)
|
||||
await interaction.response.send_message(
|
||||
"Nie jestem na kanale głosowym.", ephemeral=True
|
||||
)
|
||||
return
|
||||
await interaction.guild.voice_client.disconnect()
|
||||
self.player.clear(interaction.guild.id)
|
||||
@@ -327,9 +329,7 @@ class MusicCog(commands.Cog, name="MusicBot"):
|
||||
await self.player.trigger_state_change()
|
||||
|
||||
description = (
|
||||
"włączone (utwory po zakończeniu wracają na koniec kolejki)"
|
||||
if enabled
|
||||
else "wyłączone"
|
||||
"włączone (utwory po zakończeniu wracają na koniec kolejki)" if enabled else "wyłączone"
|
||||
)
|
||||
await interaction.response.send_message(f"🔁 Zapętlanie całej kolejki: **{description}**.")
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import Any, Awaitable, Callable
|
||||
from collections.abc import Awaitable, Callable
|
||||
from typing import Any
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
@@ -266,9 +267,7 @@ class MusicPlayer:
|
||||
def _schedule_next(self, guild_id: int, error: Exception | None) -> None:
|
||||
if error:
|
||||
logger.error("Odtwarzanie zakończone błędem na serwerze %s: %s", guild_id, error)
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
self.play_next(guild_id, advance=True), self._bot.loop
|
||||
)
|
||||
asyncio.run_coroutine_threadsafe(self.play_next(guild_id, advance=True), self._bot.loop)
|
||||
|
||||
def _record_history(self, guild_id: int, track: YTDLSource) -> None:
|
||||
if not track.title:
|
||||
|
||||
@@ -22,7 +22,9 @@ class TrackEmbedFactory:
|
||||
embed.set_footer(text=f"Pozycja w kolejce: {position} / {total}")
|
||||
return embed
|
||||
|
||||
def _base(self, track: YTDLSource, color: discord.Color, *, prefix: str = "🎵") -> discord.Embed:
|
||||
def _base(
|
||||
self, track: YTDLSource, color: discord.Color, *, prefix: str = "🎵"
|
||||
) -> discord.Embed:
|
||||
title = discord.utils.escape_markdown(track.title or "Nieznany tytuł")
|
||||
url = track.display_url
|
||||
icon = "📁" if track.is_local else prefix
|
||||
|
||||
@@ -22,7 +22,7 @@ class JsonFileStore:
|
||||
if not os.path.exists(self._path):
|
||||
return {}
|
||||
try:
|
||||
with open(self._path, "r", encoding="utf-8") as handle:
|
||||
with open(self._path, encoding="utf-8") as handle:
|
||||
data = json.load(handle)
|
||||
except (OSError, ValueError) as error:
|
||||
logger.error("Nie udało się odczytać %s: %s", self._path, error)
|
||||
|
||||
@@ -2,8 +2,8 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
from collections.abc import AsyncIterator
|
||||
from contextlib import asynccontextmanager
|
||||
from typing import AsyncIterator
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
@@ -47,7 +47,7 @@ async def play(
|
||||
try:
|
||||
track = await tracks.resolve(request.query)
|
||||
result = await player.enqueue(guild.id, track, from_web=True)
|
||||
except Exception as error: # noqa: BLE001 - treść błędu trafia do panelu
|
||||
except Exception as error:
|
||||
logger.error("Nie udało się dodać utworu z panelu: %s", error)
|
||||
raise HTTPException(status_code=500, detail=str(error)) from error
|
||||
|
||||
@@ -73,7 +73,7 @@ async def play_file(
|
||||
uploads.touch(request.filename)
|
||||
track = await tracks.from_file(uploads.resolve(request.filename))
|
||||
result = await player.enqueue(guild.id, track, from_web=True)
|
||||
except Exception as error: # noqa: BLE001
|
||||
except Exception as error:
|
||||
logger.error("Nie udało się odtworzyć pliku z panelu: %s", error)
|
||||
raise HTTPException(status_code=500, detail=str(error)) from error
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
import logging
|
||||
|
||||
from zyrarbot.web.connection_manager import ConnectionManager
|
||||
@@ -35,10 +36,8 @@ class StatusBroadcaster:
|
||||
if self._task is None:
|
||||
return
|
||||
self._task.cancel()
|
||||
try:
|
||||
with contextlib.suppress(asyncio.CancelledError):
|
||||
await self._task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
self._task = None
|
||||
|
||||
async def _loop(self) -> None:
|
||||
|
||||
@@ -75,8 +75,7 @@ class StatusService:
|
||||
str(notification_channel.id) if notification_channel else None
|
||||
),
|
||||
"history": [
|
||||
entry.to_dict()
|
||||
for entry in self._player.history(guild.id)[:HISTORY_PAYLOAD_LIMIT]
|
||||
entry.to_dict() for entry in self._player.history(guild.id)[:HISTORY_PAYLOAD_LIMIT]
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user