better __all__

This commit is contained in:
AF 2022-12-28 08:07:09 +00:00
parent 872271fc6f
commit efa124b134
33 changed files with 238 additions and 161 deletions

View File

@ -1,4 +1,3 @@
aiohttp>=3.7.4,<4
discord.py[voice]~=2.1.0
youtube_dl~=2021.12.17
yt-dlp~=2022.11.11

View File

@ -1,6 +1,6 @@
ptvp35 @ git+https://gitea.parrrate.ru/PTV/ptvp35.git@87ba808c2af1be87f4fbb9d9b3b97ba748cb9fae
v6d0auth @ git+https://gitea.parrrate.ru/PTV/v6d0auth.git@324236f435c92756aefe22877a97a906c462ef2c
v6d1tokens @ git+https://gitea.parrrate.ru/PTV/v6d1tokens.git@96567a0cb0c3cb60f20647518df5370df6dc6664
v6d2ctx @ git+https://gitea.parrrate.ru/PTV/v6d2ctx.git@d6d3b873de4e67cf41c6ce22c99f962c66e59f91
rainbowadn @ git+https://gitea.parrrate.ru/PTV/rainbowadn.git@e9fba7b064902ceedee0dd5578cb47030665a6aa
adaas @ git+https://gitea.parrrate.ru/PTV/adaas.git@5e407a73be3fc52e66a91725996087d4d11522f2
ptvp35 @ git+https://gitea.parrrate.ru/PTV/ptvp35.git@e760fca39e2070b9959aeb95b53e59e895f1ad57
v6d0auth @ git+https://gitea.parrrate.ru/PTV/v6d0auth.git@c718d4d1422945a756213d22d9e26aa24babe0f6
v6d1tokens @ git+https://gitea.parrrate.ru/PTV/v6d1tokens.git@9ada50f111bd6e9a49c9c6683fa7504fee030056
v6d2ctx @ git+https://gitea.parrrate.ru/PTV/v6d2ctx.git@18001ff3403646db46f36175a824e571c5734fd6
rainbowadn @ git+https://gitea.parrrate.ru/PTV/rainbowadn.git@fc1d11f4b53ac4653ffac1bbcad130855e1b7f10
adaas @ git+https://gitea.parrrate.ru/PTV/adaas.git@0a0da256a3be72c76fbe6af4b941ff70881d3704

12
setup.py Normal file
View File

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

View File

@ -3,14 +3,17 @@ import time
from typing import TypeAlias
import discord
from v6d3music.core.mainservice import MainService
from v6d3music.core.mainaudio import MainAudio
from v6d2ctx.context import Explicit
from v6d2ctx.context import *
from v6d3music.core.mainaudio import *
from v6d3music.core.mainservice import *
ResponseType: TypeAlias = list | dict | float | str | None
__all__ = ('Api',)
class Api:
class MisusedApi(KeyError):
def json(self) -> dict:

View File

@ -9,16 +9,17 @@ from typing import Any, Callable, Coroutine, Generic, Hashable, TypeVar
import aiohttp
import discord
from aiohttp import web
from v6d3music.api import Api
from v6d3music.config import auth_redirect, myroot
from v6d3music.core.mainservice import MainService
from v6d3music.utils.bytes_hash import bytes_hash
from ptvp35 import *
from v6d0auth.appfactory import AppFactory
from v6d0auth.run_app import start_app
from v6d1tokens.client import request_token
from v6d0auth.appfactory import *
from v6d0auth.run_app import *
from v6d1tokens.client import *
from v6d3music.api import *
from v6d3music.config import auth_redirect, myroot
from v6d3music.core.mainservice import *
from v6d3music.utils.bytes_hash import *
__all__ = ('AppContext',)
T = TypeVar('T')
TKey = TypeVar('TKey', bound=Hashable)
@ -282,6 +283,8 @@ class MusicAppFactory(AppFactory):
@routes.get('/whaturl/')
async def whaturl(request: web.Request) -> web.StreamResponse:
if request.headers.get('X-Forwarded-Proto') == 'https':
request = request.clone(scheme='https')
return web.json_response(str(request.url))

View File

@ -2,16 +2,16 @@ import shlex
from typing import Callable
from v6d3music.core.default_effects import *
from v6d3music.core.mainservice import MainService
from v6d3music.utils.assert_admin import assert_admin
from v6d3music.core.mainservice import *
from v6d3music.utils.assert_admin import *
from v6d3music.utils.catch import *
from v6d3music.utils.effects_for_preset import *
from v6d3music.utils.options_for_effects import *
from v6d3music.utils.presets import allowed_presets
from v6d3music.utils.presets import *
from v6d2ctx.at_of import AtOf
from v6d2ctx.context import Context, Explicit, command_type
from v6d2ctx.lock_for import lock_for
from v6d2ctx.at_of import *
from v6d2ctx.context import *
from v6d2ctx.lock_for import *
__all__ = ('get_of',)

View File

@ -1,11 +1,10 @@
import asyncio
from contextlib import AsyncExitStack
from v6d3music.config import myroot
from v6d3music.utils.tor_prefix import tor_prefix
from ptvp35 import *
from v6d2ctx.lock_for import lock_for
from v6d2ctx.lock_for import *
from v6d3music.config import myroot
from v6d3music.utils.tor_prefix import *
__all__ = ('Caching',)
@ -14,37 +13,45 @@ cache_root.mkdir(exist_ok=True)
class Caching:
async def _do_cache(self, hurl: str, rurl: str, tor: bool) -> None:
path = cache_root / f'{hurl}.opus'
tmp_path = cache_root / f'{hurl}.tmp.opus'
args = []
if tor:
args.extend(tor_prefix())
args.extend(
[
'ffmpeg', '-hide_banner', '-loglevel', 'warning',
'-reconnect', '1', '-reconnect_at_eof', '0',
'-reconnect_streamed', '1', '-reconnect_delay_max', '10', '-copy_unknown',
'-y', '-i', rurl, '-b:a', '128k', str(tmp_path)
]
)
ap = await asyncio.create_subprocess_exec(*args)
code = await ap.wait()
if code:
print(f'caching {hurl} failed with {code}')
return
await asyncio.to_thread(tmp_path.rename, path)
await self.__db.set(f'url:{hurl}', str(path))
async def _cache_logged(self, hurl: str, rurl: str, tor: bool) -> None:
print('caching', hurl)
await self._do_cache(hurl, rurl, tor)
print('cached', hurl)
async def _cache_url(self, hurl: str, rurl: str, override: bool, tor: bool) -> None:
if not override and self.__db.get(f'url:{hurl}', None) is not None:
return
cachable: bool = self.__db.get(f'cachable:{hurl}', False)
if cachable:
await self._cache_logged(hurl, rurl, tor)
else:
await self.__db.set(f'cachable:{hurl}', True)
async def cache_url(self, hurl: str, rurl: str, override: bool, tor: bool) -> None:
async with lock_for(('cache', hurl), 'cache failed'):
if not override and self.__db.get(f'url:{hurl}', None) is not None:
return
cachable: bool = self.__db.get(f'cachable:{hurl}', False)
if cachable:
print('caching', hurl)
path = cache_root / f'{hurl}.opus'
tmp_path = cache_root / f'{hurl}.tmp.opus'
args = []
if tor:
args.extend(tor_prefix())
args.extend(
[
'ffmpeg', '-hide_banner', '-loglevel', 'warning',
'-reconnect', '1', '-reconnect_at_eof', '0',
'-reconnect_streamed', '1', '-reconnect_delay_max', '10', '-copy_unknown',
'-y', '-i', rurl, '-b:a', '128k', str(tmp_path)
]
)
ap = await asyncio.create_subprocess_exec(*args)
code = await ap.wait()
if code:
print(f'caching {hurl} failed with {code}')
return
await asyncio.to_thread(tmp_path.rename, path)
await self.__db.set(f'url:{hurl}', str(path))
print('cached', hurl)
# await cache_db.set(f'cachable:{hurl}', False)
else:
await self.__db.set(f'cachable:{hurl}', True)
await self._cache_url(hurl, rurl, override, tor)
def get(self, hurl: str) -> str | None:
return self.__db.get(f'url:{hurl}', None)

View File

@ -1,35 +1,29 @@
import string
from v6d3music.core.real_url import real_url
from v6d2ctx.context import *
from v6d3music.core.real_url import *
from v6d3music.core.ytaservicing import *
from v6d3music.core.ytaudio import YTAudio
from v6d3music.utils.argctx import InfoCtx
from v6d3music.utils.assert_admin import assert_admin
from v6d3music.utils.options_for_effects import options_for_effects
from v6d3music.utils.presets import allowed_effects
from v6d3music.core.ytaudio import *
from v6d3music.utils.argctx import *
from v6d2ctx.context import Context, Explicit, escape
__all__ = ('create_ytaudio',)
async def _create_ytaudio(
servicing: YTAServicing, bound: BoundCtx
) -> YTAudio:
return YTAudio(
servicing,
await real_url(servicing.caching, bound.url, False, bound.tor),
bound.url,
bound.description,
bound.options,
bound.member,
bound.already_read,
bound.tor
)
async def create_ytaudio(
servicing: YTAServicing, ctx: Context, it: InfoCtx
) -> YTAudio:
assert ctx.member is not None
if it.effects:
if it.effects not in allowed_effects:
assert_admin(ctx.member)
if not set(it.effects) <= set(string.ascii_letters + string.digits + '*,=+-/()|.^:_'):
raise Explicit('malformed effects')
options = options_for_effects(it.effects)
else:
options = None
return YTAudio(
servicing,
await real_url(servicing.caching, it.info['url'], False, it.tor),
it.info['url'],
f'{escape(it.info.get("title", "unknown"))} `Rby` {ctx.member}',
options,
ctx.member,
it.already_read,
it.tor
)
bound = it.bind(ctx)
return await _create_ytaudio(servicing, bound)

View File

@ -1,10 +1,9 @@
from contextlib import AsyncExitStack
from v6d3music.config import myroot
from v6d3music.utils.presets import allowed_effects
from ptvp35 import *
from v6d2ctx.context import Explicit
from v6d2ctx.context import *
from v6d3music.config import myroot
from v6d3music.utils.presets import *
__all__ = ('DefaultEffects',)

View File

@ -6,8 +6,10 @@ from typing import Optional
import discord
from v6d3music.utils.fill import FILL
from v6d3music.utils.tor_prefix import tor_prefix
from v6d3music.utils.fill import *
from v6d3music.utils.tor_prefix import *
__all__ = ('FFmpegNormalAudio',)
class FFmpegNormalAudio(discord.FFmpegAudio):

View File

@ -1,10 +1,10 @@
import discord
from v6d3music.core.ytaservicing import *
from v6d3music.core.queueaudio import *
from v6d3music.utils.assert_admin import assert_admin
from ptvp35 import *
from v6d2ctx.context import Explicit
from v6d2ctx.context import *
from v6d3music.core.queueaudio import *
from v6d3music.core.ytaservicing import *
from v6d3music.utils.assert_admin import *
__all__ = ('MainAudio',)

View File

@ -4,6 +4,10 @@ from contextlib import AsyncExitStack
from typing import AsyncIterable, TypeVar
import discord
from ptvp35 import *
from v6d2ctx.context import *
from v6d2ctx.lock_for import *
from v6d3music.config import myroot
from v6d3music.core.caching import *
from v6d3music.core.default_effects import *
@ -15,9 +19,8 @@ from v6d3music.core.ytaudio import *
from v6d3music.processing.pool import *
from v6d3music.utils.argctx import *
from ptvp35 import *
from v6d2ctx.context import Context, Explicit
from v6d2ctx.lock_for import lock_for
__all__ = ('MainService', 'MainDescriptor', 'MainContext')
T = TypeVar('T')

View File

@ -5,13 +5,13 @@ from io import StringIO
from typing import MutableSequence
import discord
from v6d2ctx.context import Explicit
from v6d3music.core.ytaservicing import *
from v6d3music.core.ytaudio import YTAudio
from v6d3music.utils.assert_admin import assert_admin
from v6d3music.utils.fill import FILL
from ptvp35 import *
from v6d2ctx.context import *
from v6d3music.core.ytaservicing import *
from v6d3music.core.ytaudio import *
from v6d3music.utils.assert_admin import *
from v6d3music.utils.fill import *
__all__ = ('QueueAudio',)

View File

@ -1,11 +1,12 @@
import asyncio
import os
from adaas.cachedb import *
from v6d3music.core.caching import *
from v6d3music.utils.bytes_hash import bytes_hash
from v6d3music.utils.tor_prefix import tor_prefix
from v6d3music.utils.bytes_hash import *
from v6d3music.utils.tor_prefix import *
from adaas.cachedb import RemoteCache
__all__ = ('real_url',)
adaas_available = bool(os.getenv('adaasurl'))
if adaas_available:

View File

@ -3,14 +3,13 @@ from collections import deque
from contextlib import AsyncExitStack
from typing import AsyncIterable, Iterable
from v6d3music.core.ytaservicing import *
from v6d2ctx.context import *
from v6d3music.core.create_ytaudio import *
from v6d3music.core.ytaservicing import *
from v6d3music.core.ytaudio import *
from v6d3music.processing.pool import *
from v6d3music.utils.argctx import *
from v6d2ctx.context import Context
__all__ = ('YState',)

View File

@ -3,14 +3,14 @@ import random
from typing import Optional
import discord
from v6d3music.core.ffmpegnormalaudio import FFmpegNormalAudio
from v6d3music.core.real_url import real_url
from v6d3music.utils.fill import FILL
from v6d3music.utils.sparq import sparq
from v6d3music.utils.tor_prefix import tor_prefix
from v6d3music.core.ytaservicing import *
from v6d2ctx.context import Explicit
from v6d2ctx.context import *
from v6d3music.core.ffmpegnormalaudio import *
from v6d3music.core.real_url import *
from v6d3music.core.ytaservicing import *
from v6d3music.utils.fill import *
from v6d3music.utils.sparq import *
from v6d3music.utils.tor_prefix import *
__all__ = ('YTAudio',)

View File

@ -1,7 +1,7 @@
import asyncio
from typing import Any, Coroutine, Generic, TypeVar, Union
from .abstractrunner import AbstractRunner
from .abstractrunner import *
__all__ = ('Job', 'Pool', 'JobDescriptor',)

View File

@ -3,21 +3,22 @@ import contextlib
import os
import sys
import time
from traceback import print_exc
import discord
from v6d3music.app import AppContext
from ptvp35 import *
from rainbowadn.instrument import Instrumentation
from v6d1tokens.client import *
from v6d2ctx.handle_content import *
from v6d2ctx.pain import *
from v6d2ctx.serve import *
from v6d3music.app import *
from v6d3music.commands import *
from v6d3music.config import prefix
from v6d3music.core.caching import *
from v6d3music.core.default_effects import *
from v6d3music.core.mainservice import MainService
from ptvp35 import *
from rainbowadn.instrument import Instrumentation
from v6d1tokens.client import request_token
from v6d2ctx.handle_content import handle_content
from v6d2ctx.pain import ABlockMonitor
from v6d2ctx.serve import serve
from v6d3music.core.mainservice import *
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
@ -27,7 +28,7 @@ class MusicClient(discord.Client):
pass
client = MusicClient(
_client = MusicClient(
intents=discord.Intents(
members=True,
guilds=True,
@ -54,13 +55,16 @@ def message_allowed(message: discord.Message) -> bool:
return guild_allowed(message.guild)
def register_handlers(mainservice: MainService):
def register_handlers(client: discord.Client, mainservice: MainService):
of = get_of(mainservice)
@client.event
async def on_message(message: discord.Message) -> None:
if message_allowed(message):
await handle_content(of, message, message.content, prefix, client)
try:
await handle_content(of, message, message.content, prefix, client)
except:
print_exc()
@client.event
async def on_ready():
@ -135,14 +139,15 @@ def _db_ee() -> contextlib.ExitStack:
raise RuntimeError
async def main():
async def main(client: discord.Client):
async with (
client,
DefaultEffects() as defaulteffects,
MainService(defaulteffects, client) as mainservice,
AppContext(mainservice),
ABlockMonitor(delta=0.5)
):
register_handlers(mainservice)
register_handlers(client, mainservice)
if 'guerilla' in sys.argv:
from pathlib import Path
tokenpath = Path('.token.txt')
@ -164,4 +169,4 @@ async def main():
if __name__ == '__main__':
with _upgrade_abm(), _db_ee():
serve(main(), client, loop)
serve(main(_client), _client, loop)

View File

@ -1,8 +1,8 @@
import json
import v6d3music.utils.extract
from v6d3music.utils.extract import *
params = json.loads(input())
url = json.loads(input())
kwargs = json.loads(input())
print(json.dumps(v6d3music.utils.extract.extract(params, url, kwargs)))
print(json.dumps(extract(params, url, kwargs)))

View File

@ -1,7 +1,9 @@
import asyncio
from concurrent.futures import ThreadPoolExecutor
from v6d3music.utils.extract import extract
from v6d3music.utils.extract import *
__all__ = ('aextract',)
async def aextract(params: dict, url: str, **kwargs):

View File

@ -1,12 +1,15 @@
from typing import Any, AsyncIterable, Callable
import string
from typing import Any, AsyncIterable
from v6d3music.utils.effects_for_preset import effects_for_preset
from v6d3music.utils.entries_for_url import entries_for_url
from v6d3music.utils.options_for_effects import options_for_effects
from v6d3music.utils.sparq import sparq
from v6d2ctx.context import Explicit
from v6d2ctx.context import *
from v6d3music.utils.assert_admin import *
from v6d3music.utils.effects_for_preset import *
from v6d3music.utils.entries_for_url import *
from v6d3music.utils.options_for_effects import *
from v6d3music.utils.presets import *
from v6d3music.utils.sparq import *
__all__ = ('InfoCtx', 'UrlCtx', 'ArgCtx',)
__all__ = ('InfoCtx', 'BoundCtx', 'UrlCtx', 'ArgCtx',)
class InfoCtx:
@ -19,6 +22,34 @@ class InfoCtx:
self.tor = tor
self.ignore = ignore
def bind(self, ctx: Context) -> 'BoundCtx':
return BoundCtx(self, ctx)
class BoundCtx:
def __init__(self, it: InfoCtx, ctx: Context, /) -> None:
if ctx.member is None:
raise Explicit('not in a guild')
self.member = ctx.member
self.ctx = ctx
self.url = it.info['url']
self.description = f'{escape(it.info.get("title", "unknown"))} `Rby` {ctx.member}'
self.tor = it.tor
self.effects = it.effects
self.already_read = it.already_read
self.options = self._options()
def _options(self) -> str | None:
assert self.ctx.member is not None
if self.effects:
if self.effects not in allowed_effects:
assert_admin(self.ctx.member)
if not set(self.effects) <= set(string.ascii_letters + string.digits + '*,=+-/()|.^:_'):
raise Explicit('malformed effects')
options = options_for_effects(self.effects)
else:
options = None
class UrlCtx:
def __init__(self, url: str, effects: str | None) -> None:

View File

@ -1,5 +1,8 @@
import discord
from v6d2ctx.context import Explicit
from v6d2ctx.context import *
__all__ = ('assert_admin',)
def assert_admin(member: discord.Member | None):

View File

@ -1,5 +1,7 @@
import nacl.hash
__all__ = ('bytes_hash',)
def bytes_hash(b: bytes) -> str:
return nacl.hash.sha256(b).decode()

View File

@ -1,6 +1,6 @@
from typing import Iterable
from v6d2ctx.context import Context, Implicit
from v6d2ctx.context import *
__all__ = ('catch',)

View File

@ -1,7 +1,5 @@
from v6d2ctx.context import Explicit
from v6d3music.utils.presets import presets
from v6d2ctx.context import *
from v6d3music.utils.presets import *
__all__ = ('effects_for_preset',)

View File

@ -1,9 +1,10 @@
from typing import Any, AsyncIterable
from v6d2ctx.context import Explicit
from v6d2ctx.context import *
from v6d3music.utils.aextract import *
from v6d3music.utils.tor_extract import *
from v6d3music.utils.aextract import aextract
from v6d3music.utils.tor_extract import tor_extract
__all__ = ('entries_for_url',)
async def entries_for_url(url: str, tor: bool) -> AsyncIterable[

View File

@ -1,6 +1,8 @@
import discord.utils
import yt_dlp
__all__ = ('extract',)
def extract(params: dict, url: str, kwargs: dict):
try:

View File

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

View File

@ -1,16 +1,18 @@
normal = 'loudnorm=i=-12'
__all__ = ('normal_prefix', '_prefix_preset', 'presets', 'allowed_presets', 'allowed_effects')
normal_prefix = 'loudnorm=i=-12'
# _prefix = f'{normal},'
_prefix = f''
_prefix_preset = f''
presets: dict[str, str] = {
'cursed': 'aeval=val(0)*2*sin(440*t)+val(1)*2*cos(622*t)|val(1)*2*sin(622*t)+val(0)*2*cos(440*t)',
'bassboost': f'{_prefix}bass=g=10',
'bassbooboost': f'{_prefix}bass=g=30',
'nightcore': f'{_prefix}asetrate=67882',
'daycore': f'{_prefix}atempo=.9,aecho=1.0:0.5:20:0.5',
'bassboost': f'{_prefix_preset}bass=g=10',
'bassbooboost': f'{_prefix_preset}bass=g=30',
'nightcore': f'{_prefix_preset}asetrate=67882',
'daycore': f'{_prefix_preset}atempo=.9,aecho=1.0:0.5:20:0.5',
'пришествие анимешне': 'bass=g=15,asetrate=67882,bass=g=15',
'difference': 'aeval=val(0)-val(1)|val(1)-val(0)',
'mono': f'{_prefix}aeval=.5*val(0)+.5*val(1)|.5*val(1)+.5*val(0)',
'normal': f'{normal}',
'mono': f'{_prefix_preset}aeval=.5*val(0)+.5*val(1)|.5*val(1)+.5*val(0)',
'normal': f'{normal_prefix}',
}
allowed_presets = ['bassboost', 'bassbooboost', 'nightcore', 'daycore', 'mono', 'normal', ]
allowed_effects = {'', *(presets[key] for key in allowed_presets)}

View File

@ -1,6 +1,9 @@
import discord
from v6d3music.utils.speed_quotient import speed_quotient
from v6d3music.utils.speed_quotient import *
__all__ = ('sparq',)
def sparq(options: str | None) -> float:

View File

@ -2,6 +2,8 @@ import re
import discord
__all__ = ('speed_quotient',)
def speed_quotient(options: str | None) -> float:
options = options or ''

View File

@ -1,7 +1,9 @@
import asyncio
import json
from v6d3music.utils.tor_prefix import tor_prefix
from v6d3music.utils.tor_prefix import *
__all__ = ('tor_extract',)
async def tor_extract(params: dict, url: str, **kwargs):

View File

@ -1,3 +1,3 @@
__all__ = ('tor_prefix',)
from adaas.tor_prefix import tor_prefix
from adaas.tor_prefix import *