From ccb322d08ea0b1c5fd74fa63f74550e264346017 Mon Sep 17 00:00:00 2001 From: Will Date: Sun, 11 Mar 2018 19:49:08 -0400 Subject: [PATCH] [Audio] V3/auto autostart only (#1420) * Download jar at audio load * Messy... * Remove leftover log file stuff * Keep application.yml * Damn you windows --- redbot/cogs/audio/__init__.py | 53 +++++++++++++++++++++++++++++++++-- redbot/cogs/audio/audio.py | 14 ++++----- redbot/cogs/audio/manager.py | 41 +++++++++++++++++++++++++++ setup.py | 1 + 4 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 redbot/cogs/audio/manager.py diff --git a/redbot/cogs/audio/__init__.py b/redbot/cogs/audio/__init__.py index 0c0777ca0..2e3805c4b 100644 --- a/redbot/cogs/audio/__init__.py +++ b/redbot/cogs/audio/__init__.py @@ -1,8 +1,57 @@ +from pathlib import Path +from aiohttp import ClientSession +import shutil +import asyncio + from .audio import Audio +from .manager import start_lavalink_server from discord.ext import commands +from redbot.core.data_manager import cog_data_path + +LAVALINK_BUILD = 3065 +LAVALINK_BUILD_URL = ( + "https://ci.fredboat.com/repository/download/" + "Lavalink_Build/{}:id/Lavalink.jar?guest=1" +).format(LAVALINK_BUILD) + +LAVALINK_DOWNLOAD_DIR = cog_data_path(raw_name="Audio") +LAVALINK_JAR_FILE = LAVALINK_DOWNLOAD_DIR / "Lavalink.jar" + +APP_YML_FILE = LAVALINK_DOWNLOAD_DIR / "application.yml" +BUNDLED_APP_YML_FILE = Path(__file__).parent / "application.yml" + + +async def download_lavalink(session): + with LAVALINK_JAR_FILE.open(mode='wb') as f: + async with session.get(LAVALINK_BUILD_URL) as resp: + while True: + chunk = await resp.content.read(512) + if not chunk: + break + f.write(chunk) + + +async def maybe_download_lavalink(loop, cog): + jar_exists = LAVALINK_JAR_FILE.exists() + current_build = await cog.config.current_build() + + if not jar_exists or current_build < LAVALINK_BUILD: + LAVALINK_DOWNLOAD_DIR.mkdir(parents=True, exist_ok=True) + with ClientSession(loop=loop) as session: + await download_lavalink(session) + await cog.config.current_build.set(LAVALINK_BUILD) + + shutil.copyfile(str(BUNDLED_APP_YML_FILE), str(APP_YML_FILE)) async def setup(bot: commands.Bot): cog = Audio(bot) - await cog.init_config() - bot.add_cog(cog) + await maybe_download_lavalink(bot.loop, cog) + await start_lavalink_server(bot.loop) + + async def _finish(): + await asyncio.sleep(10) + await cog.init_config() + bot.add_cog(cog) + + bot.loop.create_task(_finish()) diff --git a/redbot/cogs/audio/audio.py b/redbot/cogs/audio/audio.py index da2607d24..59aa16312 100644 --- a/redbot/cogs/audio/audio.py +++ b/redbot/cogs/audio/audio.py @@ -9,13 +9,12 @@ import math from discord.ext import commands from redbot.core import Config, checks +from .manager import shutdown_lavalink_server + __version__ = "2.0.2.9.b" __author__ = ["aikaterna", "billy/bollo/ati"] -LAVALINK_BUILD = 3065 - - class Audio: def __init__(self, bot): self.bot = bot @@ -25,7 +24,8 @@ class Audio: "host": 'localhost', "port": '2332', "passw": 'youshallnotpass', - "status": False + "status": False, + "current_build": 0 } default_guild = { @@ -39,10 +39,6 @@ class Audio: self.config.register_global(**default_global) self._lavalink = None - self._lavalink_build_url = ( - "https://ci.fredboat.com/repository/download/" - "Lavalink_Build/{}:id/Lavalink.jar" - ).format(LAVALINK_BUILD) async def init_config(self): host = await self.config.host() @@ -822,4 +818,6 @@ class Audio: return queue_total_duration def __unload(self): + self.bot.lavalink.ws._ws.close() self.bot.lavalink.client.destroy() + shutdown_lavalink_server() diff --git a/redbot/cogs/audio/manager.py b/redbot/cogs/audio/manager.py new file mode 100644 index 000000000..f83ef6254 --- /dev/null +++ b/redbot/cogs/audio/manager.py @@ -0,0 +1,41 @@ +import shlex +import asyncio +from subprocess import Popen, DEVNULL +import os + +proc = None +SHUTDOWN = asyncio.Event() + + +async def monitor_lavalink_server(loop): + while not SHUTDOWN.is_set(): + if proc.poll() is not None: + break + await asyncio.sleep(0.5) + + if not SHUTDOWN.is_set(): + print("Lavalink jar shutdown, restarting.") + await start_lavalink_server(loop) + + +async def start_lavalink_server(loop): + from . import LAVALINK_DOWNLOAD_DIR, LAVALINK_JAR_FILE + start_cmd = "java -jar {}".format(LAVALINK_JAR_FILE.resolve()) + + global proc + proc = Popen( + shlex.split(start_cmd, posix=os.name == 'posix'), + cwd=str(LAVALINK_DOWNLOAD_DIR), + stdout=DEVNULL, stderr=DEVNULL + ) + + print("Lavalink jar started. PID: {}".format(proc.pid)) + + loop.create_task(monitor_lavalink_server(loop)) + + +def shutdown_lavalink_server(): + print("Shutting down lavalink server.") + SHUTDOWN.set() + if proc is not None: + proc.terminate() diff --git a/setup.py b/setup.py index cb44b2f46..012b36c35 100644 --- a/setup.py +++ b/setup.py @@ -96,6 +96,7 @@ setup( version="{}.{}.{}b9".format(*get_version()), packages=get_package_list(), package_data=find_locale_folders(), + include_package_data=True, url='https://github.com/Cog-Creators/Red-DiscordBot', license='GPLv3', author='Cog-Creators',