v6d3music/v6d3music/core/cache_url.py
2022-11-01 18:35:10 +00:00

51 lines
1.8 KiB
Python

import asyncio
import subprocess
from ptvp35 import Db, KVJson
from v6d2ctx.context import Benchmark
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)
]
)
p = subprocess.Popen(
args,
)
loop = asyncio.get_running_loop()
with Benchmark('CCH'):
code = await loop.run_in_executor(None, p.wait)
if code:
print(f'caching {hurl} failed with {code}')
return
await loop.run_in_executor(None, 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)