This commit is contained in:
AF 2023-10-02 19:12:46 +00:00
parent 89ac8a491b
commit c085feea71
14 changed files with 58 additions and 53 deletions

View File

@ -8,26 +8,27 @@
import os.path import os.path
import sys import sys
project = 'parrrate-music'
copyright = '2022, PARRRATE TNV' project = "parrrate-music"
author = 'PARRRATE TNV' copyright = "2022, PARRRATE TNV"
author = "PARRRATE TNV"
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = [ extensions = [
'sphinx.ext.autodoc', "sphinx.ext.autodoc",
] ]
templates_path = ['_templates'] templates_path = ["_templates"]
exclude_patterns = [] exclude_patterns = []
# -- Options for HTML output ------------------------------------------------- # -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = 'pydata_sphinx_theme' html_theme = "pydata_sphinx_theme"
html_static_path = ['_static'] html_static_path = ["_static"]
sys.path.insert(0, os.path.abspath('../..')) sys.path.insert(0, os.path.abspath("../.."))

View File

@ -1,12 +1,12 @@
from setuptools import setup from setuptools import setup
setup( setup(
name='v6d3music', name="v6d3music",
version='', version="",
packages=['v6d3music'], packages=["v6d3music"],
url='', url="",
license='', license="",
author='PARRRATE TNV', author="PARRRATE TNV",
author_email='', author_email="",
description='' description="",
) )

View File

@ -1,3 +1,3 @@
__all__ = ('api', 'app', 'commands', 'config') __all__ = ("api", "app", "commands", "config")
from . import api, app, commands, config from . import api, app, commands, config

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import asyncio import asyncio
import time import time
@ -118,7 +120,7 @@ class UserApi:
sub._key = key sub._key = key
return sub return sub
async def to_guild_api(self, guild_id: int) -> "GuildApi": async def to_guild_api(self, guild_id: int) -> GuildApi:
guild = self.client.get_guild(guild_id) or await self.client.fetch_guild(guild_id) guild = self.client.get_guild(guild_id) or await self.client.fetch_guild(guild_id)
if guild is None: if guild is None:
raise UserApi.UnknownMember("unknown guild") raise UserApi.UnknownMember("unknown guild")
@ -127,7 +129,7 @@ class UserApi:
raise UserApi.UnknownMember("unknown member of a guild") raise UserApi.UnknownMember("unknown member of a guild")
return GuildApi(self, member) return GuildApi(self, member)
async def to_operator_api(self) -> "OperatorApi": async def to_operator_api(self) -> OperatorApi:
if not self.pi.is_operator(self.user_id): if not self.pi.is_operator(self.user_id):
raise UserApi.UnknownMember("not an operator") raise UserApi.UnknownMember("not an operator")
return OperatorApi(self) return OperatorApi(self)
@ -188,7 +190,7 @@ class GuildApi(UserApi):
self.member = member self.member = member
self.guild = member.guild self.guild = member.guild
async def to_voice_api(self) -> "VoiceApi": async def to_voice_api(self) -> VoiceApi:
voice = self.member.voice voice = self.member.voice
if voice is None: if voice is None:
raise GuildApi.VoiceNotConnected("you are not connected to voice") raise GuildApi.VoiceNotConnected("you are not connected to voice")

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from contextlib import AsyncExitStack from contextlib import AsyncExitStack
from ptvp35 import DbFactory, KVJson from ptvp35 import DbFactory, KVJson
@ -21,11 +23,12 @@ class DefaultEffects:
raise Explicit("these effects are not allowed") raise Explicit("these effects are not allowed")
await self.__db.set(gid, effects) await self.__db.set(gid, effects)
async def __aenter__(self) -> "DefaultEffects": async def __aenter__(self) -> DefaultEffects:
async with AsyncExitStack() as es: async with AsyncExitStack() as es:
self.__db = await es.enter_async_context(DbFactory(myroot / "effects.db", kvfactory=KVJson())) self.__db = await es.enter_async_context(DbFactory(myroot / "effects.db", kvfactory=KVJson()))
self.__es = es.pop_all() self.__es = es.pop_all()
return self return self
raise RuntimeError
async def __aexit__(self, exc_type, exc_val, exc_tb): async def __aexit__(self, exc_type, exc_val, exc_tb):
async with self.__es: async with self.__es:

View File

@ -99,10 +99,10 @@ class MainService:
raise Explicit("not in a guild") raise Explicit("not in a guild")
return await self.raw_vc_for_member(ctx.member) return await self.raw_vc_for_member(ctx.member)
def mode(self, *, create: bool, force_play: bool) -> "MainMode": def mode(self, *, create: bool, force_play: bool) -> MainMode:
return MainMode(self, create=create, force_play=force_play) return MainMode(self, create=create, force_play=force_play)
def context(self, ctx: Context, *, create: bool, force_play: bool) -> "MainContext": def context(self, ctx: Context, *, create: bool, force_play: bool) -> MainContext:
return self.mode(create=create, force_play=force_play).context(ctx) return self.mode(create=create, force_play=force_play).context(ctx)
async def create(self, guild: discord.Guild) -> MainAudio: async def create(self, guild: discord.Guild) -> MainAudio:
@ -266,7 +266,7 @@ class MainMode:
vc.play(source) vc.play(source)
return source return source
def context(self, ctx: Context) -> "MainContext": def context(self, ctx: Context) -> MainContext:
return MainContext(self, ctx) return MainContext(self, ctx)

View File

@ -1,4 +1,6 @@
__all__ = ('Monitoring', 'PersistentMonitoring') from __future__ import annotations
__all__ = ("Monitoring", "PersistentMonitoring")
import asyncio import asyncio
from contextlib import AsyncExitStack, ExitStack from contextlib import AsyncExitStack, ExitStack
@ -6,7 +8,7 @@ from typing import Any, Callable, Generic, TypeVar
from rainbowadn.instrument import Instrumentation from rainbowadn.instrument import Instrumentation
T = TypeVar('T', bound=Instrumentation, covariant=True) T = TypeVar("T", bound=Instrumentation, covariant=True)
class Provider(Generic[T]): class Provider(Generic[T]):
@ -19,7 +21,7 @@ class Provider(Generic[T]):
def __enter__(self) -> T: def __enter__(self) -> T:
if self.__closed: if self.__closed:
raise RuntimeError('the provider is closed') raise RuntimeError("the provider is closed")
if self.__count < 0: if self.__count < 0:
raise RuntimeError raise RuntimeError
if self.__count == 0: if self.__count == 0:
@ -62,19 +64,15 @@ class ProviderManager(Generic[T]):
class Monitoring: class Monitoring:
async def get(self, provider: Callable[[], T]) -> Provider[T]: async def get(self, provider: Callable[[], T]) -> Provider[T]:
if provider not in self.__providers: if provider not in self.__providers:
self.__providers[provider] = asyncio.create_task( self.__providers[provider] = asyncio.create_task(self.__es.enter_async_context(ProviderManager(provider)))
self.__es.enter_async_context(ProviderManager(provider))
)
return await self.__providers[provider] return await self.__providers[provider]
async def __aenter__(self) -> 'Monitoring': async def __aenter__(self) -> "Monitoring":
async with AsyncExitStack() as es: async with AsyncExitStack() as es:
self.__providers: dict[ self.__providers: dict[Callable[[], Instrumentation], asyncio.Future[Provider]] = {}
Callable[[], Instrumentation],
asyncio.Future[Provider]
] = {}
self.__es = es.pop_all() self.__es = es.pop_all()
return self return self
raise RuntimeError
async def __aexit__(self, exc_type, exc_val, exc_tb): async def __aexit__(self, exc_type, exc_val, exc_tb):
async with self.__es: async with self.__es:
@ -90,16 +88,11 @@ class PersistentMonitoring:
async def get(self, provider: Callable[[], T]) -> T: async def get(self, provider: Callable[[], T]) -> T:
if provider not in self.__instrumentations: if provider not in self.__instrumentations:
self.__instrumentations[provider] = asyncio.create_task( self.__instrumentations[provider] = asyncio.create_task(self._get(provider))
self._get(provider)
)
return await self.__instrumentations[provider] return await self.__instrumentations[provider]
def __enter__(self) -> 'PersistentMonitoring': def __enter__(self) -> PersistentMonitoring:
self.__instrumentations: dict[ self.__instrumentations: dict[Callable[[], Instrumentation], asyncio.Future] = {}
Callable[[], Instrumentation],
asyncio.Future
] = {}
self.__es = ExitStack() self.__es = ExitStack()
return self return self

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import asyncio import asyncio
import random import random
import traceback import traceback
@ -53,7 +55,7 @@ class QueueAudio(discord.AudioSource):
return respawned return respawned
@classmethod @classmethod
async def create(cls, servicing: YTAServicing, db: DbConnection, guild: discord.Guild) -> "QueueAudio": async def create(cls, servicing: YTAServicing, db: DbConnection, guild: discord.Guild) -> QueueAudio:
return cls(db, guild, await cls.respawned(servicing, db, guild)) return cls(db, guild, await cls.respawned(servicing, db, guild))
async def save(self, delay: bool) -> None: async def save(self, delay: bool) -> None:

View File

@ -17,8 +17,10 @@ async def repeat(repeated: Callable[[], Coroutine[Any, Any, T]]) -> T:
async def set_config(key: str, value: Any) -> None: async def set_config(key: str, value: Any) -> None:
json = {"key": key, "value": value} json = {"key": key, "value": value}
async def call() -> None: async def call() -> None:
async with aiohttp.ClientSession() as s, s.post("http://sessionservice/config/", json=json) as response: async with aiohttp.ClientSession() as s, s.post("http://sessionservice/config/", json=json) as response:
if response.status != 200: if response.status != 200:
raise RuntimeError("config request failed") raise RuntimeError("config request failed")
await repeat(call) await repeat(call)

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import asyncio import asyncio
import random import random
import re import re
@ -222,7 +224,7 @@ class YTAudio(discord.AudioSource):
} }
@classmethod @classmethod
async def respawn(cls, servicing: YTAServicing, guild: discord.Guild, respawn: dict) -> "YTAudio": async def respawn(cls, servicing: YTAServicing, guild: discord.Guild, respawn: dict) -> YTAudio:
member_id: int | None = respawn["rby"] member_id: int | None = respawn["rby"]
if member_id is None: if member_id is None:
member = None member = None
@ -267,7 +269,7 @@ class YTAudio(discord.AudioSource):
"canbeskipped": self.can_be_skipped_by(member), "canbeskipped": self.can_be_skipped_by(member),
} }
def copy(self) -> "YTAudio": def copy(self) -> YTAudio:
return YTAudio( return YTAudio(
self.servicing, self.servicing,
self.url, self.url,
@ -278,7 +280,7 @@ class YTAudio(discord.AudioSource):
0, 0,
) )
def branch(self) -> "YTAudio": def branch(self) -> YTAudio:
if self.stop_at is not None: if self.stop_at is not None:
raise Explicit("already branched") raise Explicit("already branched")
self.stop_at = stop_at = self.already_read + 50 self.stop_at = stop_at = self.already_read + 50

View File

@ -1,4 +1,4 @@
from .main import main from .main import main
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View File

@ -1,6 +1,6 @@
import nacl.hash import nacl.hash
__all__ = ('bytes_hash',) __all__ = ("bytes_hash",)
def bytes_hash(b: bytes) -> str: def bytes_hash(b: bytes) -> str:

View File

@ -1,5 +1,5 @@
import discord import discord
__all__ = ('FILL',) __all__ = ("FILL",)
FILL = b'\x00' * discord.opus.Encoder.FRAME_SIZE FILL = b"\x00" * discord.opus.Encoder.FRAME_SIZE

View File

@ -1,8 +1,8 @@
import shlex import shlex
from typing import Optional from typing import Optional
__all__ = ('options_for_effects',) __all__ = ("options_for_effects",)
def options_for_effects(effects: str | None) -> Optional[str]: def options_for_effects(effects: str | None) -> Optional[str]:
return f'-af {shlex.quote(effects)}' if effects else None return f"-af {shlex.quote(effects)}" if effects else None