v6d3music/v6d3music/core/cache_url.py
2022-11-11 11:02:10 +00:00

45 lines
1.6 KiB
Python

import asyncio
from ptvp35 import Db, KVJson
from v6d2ctx.lock_for import lock_for
from v6d3music.config import myroot
from v6d3music.utils.tor_prefix import tor_prefix
cache_root = myroot / 'cache'
cache_root.mkdir(exist_ok=True)
cache_db = Db(myroot / 'cache.db', kvrequest_type=KVJson)
async def cache_url(hurl: str, rurl: str, override: bool, tor: bool) -> None:
async with lock_for(('cache', hurl), 'cache failed'):
if not override and cache_db.get(f'url:{hurl}', None) is not None:
return
cachable: bool = cache_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 cache_db.set(f'url:{hurl}', str(path))
print('cached', hurl)
# await cache_db.set(f'cachable:{hurl}', False)
else:
await cache_db.set(f'cachable:{hurl}', True)