update(main): improve launch UI

This commit is contained in:
Romain J 2020-08-28 01:06:57 +02:00
parent c1e253689d
commit 9a0786af7c
11 changed files with 156 additions and 67 deletions

View file

@ -25,4 +25,4 @@ If applicable, add screenshots to help explain your problem.
- Python Version [e.g. 3.7.4] - Python Version [e.g. 3.7.4]
**Additional context** **Additional context**
Add any other context about the problem here. <-- Add any other context about the problem here. -->

View file

@ -1,16 +1,19 @@
<component name="ProjectDictionaryState"> <component name="ProjectDictionaryState">
<dictionary name="romain"> <dictionary name="romain">
<words> <words>
<w>asctime</w>
<w>commandstats</w> <w>commandstats</w>
<w>francais</w> <w>francais</w>
<w>ipinfo</w> <w>ipinfo</w>
<w>iplocalise</w> <w>iplocalise</w>
<w>levelname</w>
<w>localiseip</w> <w>localiseip</w>
<w>postgresql</w> <w>postgresql</w>
<w>socketstats</w> <w>socketstats</w>
<w>splt</w> <w>splt</w>
<w>systemd</w> <w>systemd</w>
<w>tutux</w> <w>tutux</w>
<w>tuxbot</w>
<w>tuxvenv</w> <w>tuxvenv</w>
<w>webhooks</w> <w>webhooks</w>
</words> </words>

View file

@ -1,10 +1,16 @@
import subprocess import os
from collections import namedtuple from collections import namedtuple
build = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).decode() build = os.popen('git rev-parse --short HEAD').read().strip()
info = os.popen('git log -n 1 -s --format="%s"').read().strip()
VersionInfo = namedtuple("VersionInfo", "major minor micro releaselevel build") VersionInfo = namedtuple(
version_info = VersionInfo(major=3, minor=0, micro=0, releaselevel="alpha", build=build) "VersionInfo", "major minor micro releaselevel build, info"
)
version_info = VersionInfo(
major=3, minor=0, micro=0,
releaselevel="alpha", build=build, info=info
)
__version__ = "v{}.{}.{}-{}.{}".format( __version__ = "v{}.{}.{}-{}.{}".format(
version_info.major, version_info.major,
@ -13,3 +19,9 @@ __version__ = "v{}.{}.{}-{}.{}".format(
version_info.releaselevel, version_info.releaselevel,
version_info.build, version_info.build,
).replace("\n", "") ).replace("\n", "")
class ExitCodes:
CRITICAL = 1
SHUTDOWN = 0
RESTART = 42

View file

@ -6,22 +6,30 @@ import logging
import platform import platform
import signal import signal
import sys import sys
import os
from argparse import Namespace from argparse import Namespace
from typing import NoReturn from typing import NoReturn
import discord import discord
import pip import pip
from colorama import Fore, init, Style
from pip._vendor import distro from pip._vendor import distro
from rich.columns import Columns
from rich.console import Console
from rich.panel import Panel
from rich.traceback import install
from rich.table import Table, box
from rich.text import Text
from rich import print
import tuxbot.logging import tuxbot.logging
from tuxbot.core import data_manager from tuxbot.core import data_manager
from tuxbot.core.bot import Tux, ExitCodes from tuxbot.core.bot import Tux
from tuxbot.core.utils.functions.cli import bordered from . import __version__, version_info, ExitCodes
from . import __version__
log = logging.getLogger("tuxbot.main") log = logging.getLogger("tuxbot.main")
init()
console = Console()
install(console=console)
def list_instances() -> NoReturn: def list_instances() -> NoReturn:
@ -29,16 +37,33 @@ def list_instances() -> NoReturn:
""" """
with data_manager.config_file.open() as fs: with data_manager.config_file.open() as fs:
datas = json.load(fs) data = json.load(fs)
info = {"title": "Instances", "rows": []} console.print(
Panel("[bold green]Instances", style="green"),
for instance, details in datas.items(): justify="center"
info["rows"].append(
f"-> {instance} " f"{'up' if details.get('IS_RUNNING') else 'down'}"
) )
console.print()
columns = Columns(expand=True, padding=2, align="center")
for instance, details in data.items():
is_running = details.get('IS_RUNNING')
table = Table(
style="dim", border_style="not dim",
box=box.HEAVY_HEAD
)
table.add_column("Name")
table.add_column(("Running" if is_running else "Down") + " since")
table.add_row(instance, "42")
table.title = Text(
instance,
style="green" if is_running else "red"
)
columns.add_renderable(table)
console.print(columns)
console.print()
print(bordered(info))
sys.exit(0) sys.exit(0)
@ -56,23 +81,62 @@ def debug_info() -> NoReturn:
runner = getpass.getuser() runner = getpass.getuser()
info = { uname = os.popen('uname -a').read().strip().split()
"title": "Debug Info", uptime = os.popen('uptime').read().strip().split()
"rows": [
f"Tuxbot version: {tuxbot_version}",
"",
f"Python version: {python_version}",
f"Python executable path: {sys.executable}",
f"Pip version: {pip_version}",
f"Discord.py version: {dpy_version}",
"",
f"OS info: {os_info}",
f"System arch: {platform.machine()}",
f"User: {runner}",
],
}
print(bordered(info)) console.print(
Panel("[bold blue]Debug Info", style="blue"),
justify="center"
)
console.print()
columns = Columns(expand=True, padding=2, align="center")
table = Table(
style="dim", border_style="not dim",
box=box.HEAVY_HEAD
)
table.add_column(
"Bot Info",
)
table.add_row(f"[u]Tuxbot version:[/u] {tuxbot_version}")
table.add_row(f"[u]Major:[/u] {version_info.major}")
table.add_row(f"[u]Minor:[/u] {version_info.minor}")
table.add_row(f"[u]Micro:[/u] {version_info.micro}")
table.add_row(f"[u]Level:[/u] {version_info.releaselevel}")
table.add_row(f"[u]Last change:[/u] {version_info.info}")
columns.add_renderable(table)
table = Table(
style="dim", border_style="not dim",
box=box.HEAVY_HEAD
)
table.add_column(
"Python Info",
)
table.add_row(f"[u]Python version:[/u] {python_version}")
table.add_row(f"[u]Python executable path:[/u] {sys.executable}")
table.add_row(f"[u]Pip version:[/u] {pip_version}")
table.add_row(f"[u]Discord.py version:[/u] {dpy_version}")
columns.add_renderable(table)
table = Table(
style="dim", border_style="not dim",
box=box.HEAVY_HEAD
)
table.add_column(
"Server Info",
)
table.add_row(f"[u]OS:[/u] {os_info}")
table.add_row(f"[u]Kernel:[/u] {uname[2]}")
table.add_row(f"[u]System arch:[/u] {platform.machine()}")
table.add_row(f"[u]User:[/u] {runner}")
table.add_row(f"[u]Uptime:[/u] {uptime[2]}")
table.add_row(f"[u]Load Average:[/u] {' '.join(uptime[-3:])}")
columns.add_renderable(table)
console.print(columns)
console.print()
sys.exit(0) sys.exit(0)
@ -92,13 +156,17 @@ def parse_cli_flags(args: list) -> Namespace:
usage="tuxbot <instance_name> [arguments]", usage="tuxbot <instance_name> [arguments]",
) )
parser.add_argument( parser.add_argument(
"--version", "-V", action="store_true", help="Show tuxbot's used version" "--version", "-V", action="store_true",
help="Show tuxbot's used version"
) )
parser.add_argument("--debug", action="store_true", help="Show debug information.") parser.add_argument("--debug", action="store_true",
help="Show debug information.")
parser.add_argument( parser.add_argument(
"--list-instances", "-L", action="store_true", help="List all instance names" "--list-instances", "-L", action="store_true",
help="List all instance names"
) )
parser.add_argument("--token", "-T", type=str, help="Run Tuxbot with passed token") parser.add_argument("--token", "-T", type=str,
help="Run Tuxbot with passed token")
parser.add_argument( parser.add_argument(
"instance_name", "instance_name",
nargs="?", nargs="?",
@ -137,7 +205,8 @@ async def shutdown_handler(tux: Tux, signal_type, exit_code=None) -> NoReturn:
try: try:
await tux.logout() await tux.logout()
finally: finally:
pending = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] pending = [t for t in asyncio.all_tasks() if
t is not asyncio.current_task()]
for task in pending: for task in pending:
task.cancel() task.cancel()
@ -181,6 +250,7 @@ async def run_bot(tux: Tux, cli_flags: Namespace) -> None:
await tux.start(token, bot=True) await tux.start(token, bot=True)
except discord.LoginFailure: except discord.LoginFailure:
log.critical("This token appears to be valid.") log.critical("This token appears to be valid.")
console.print_exception()
sys.exit(ExitCodes.CRITICAL) sys.exit(ExitCodes.CRITICAL)
return None return None
@ -207,10 +277,9 @@ def main() -> NoReturn:
try: try:
if not cli_flags.instance_name: if not cli_flags.instance_name:
print( console.print(
Fore.RED + "No instance provided ! " "[red]No instance provided ! "
"You can use 'tuxbot -L' to list all available instances" "You can use 'tuxbot -L' to list all available instances"
+ Style.RESET_ALL
) )
sys.exit(ExitCodes.CRITICAL) sys.exit(ExitCodes.CRITICAL)
@ -222,10 +291,8 @@ def main() -> NoReturn:
loop.run_until_complete(run_bot(tux, cli_flags)) loop.run_until_complete(run_bot(tux, cli_flags))
except KeyboardInterrupt: except KeyboardInterrupt:
print( console.print(
Fore.RED "[red]Please use <prefix>quit instead of Ctrl+C to Shutdown!"
+ "Please use <prefix>quit instead of Ctrl+C to Shutdown!"
+ Style.RESET_ALL
) )
log.warning("Please use <prefix>quit instead of Ctrl+C to Shutdown!") log.warning("Please use <prefix>quit instead of Ctrl+C to Shutdown!")
log.error("Received KeyboardInterrupt") log.error("Received KeyboardInterrupt")
@ -251,4 +318,7 @@ def main() -> NoReturn:
if __name__ == "__main__": if __name__ == "__main__":
try:
main() main()
except Exception:
console.print_exception()

View file

@ -3,14 +3,14 @@ from collections import namedtuple
from .admin import Admin from .admin import Admin
from ...core.bot import Tux from ...core.bot import Tux
VersionInfo = namedtuple("VersionInfo", "major minor micro releaselevel") VersionInfo = namedtuple("VersionInfo", "major minor micro release_level")
version_info = VersionInfo(major=2, minor=0, micro=0, releaselevel="alpha") version_info = VersionInfo(major=2, minor=0, micro=0, release_level="alpha")
__version__ = "v{}.{}.{}-{}".format( __version__ = "v{}.{}.{}-{}".format(
version_info.major, version_info.major,
version_info.minor, version_info.minor,
version_info.micro, version_info.micro,
version_info.releaselevel, version_info.release_level,
).replace("\n", "") ).replace("\n", "")

View file

@ -24,6 +24,7 @@ class Admin(commands.Cog, name="Admin"):
@checks.is_admin() @checks.is_admin()
async def _lang(self, ctx: ContextPlus): async def _lang(self, ctx: ContextPlus):
"""Manage lang settings.""" """Manage lang settings."""
pass
@_lang.command(name="set", aliases=["define", "choice"]) @_lang.command(name="set", aliases=["define", "choice"])
async def _lang_set(self, ctx: ContextPlus, lang: str): async def _lang_set(self, ctx: ContextPlus, lang: str):

View file

@ -15,7 +15,7 @@ class Warnings(commands.Cog, name="Warnings"):
@commands.guild_only() @commands.guild_only()
@checks.is_mod() @checks.is_mod()
async def _warn(self, ctx: commands.Context): async def _warn(self, ctx: commands.Context):
pass division_by_zero = 1 / 0
@_warn.command(name="add") @_warn.command(name="add")
@commands.guild_only() @commands.guild_only()

View file

@ -1,8 +1,10 @@
from colorama import init from .. import __version__, version_info, VersionInfo, ExitCodes
from .. import __version__, version_info, VersionInfo
from .config import Config from .config import Config
__all__ = ["Config", "__version__", "version_info", "VersionInfo"] __all__ = [
"Config",
init() "__version__",
"version_info",
"VersionInfo",
"ExitCodes",
]

View file

@ -5,18 +5,20 @@ import sys
from typing import List, Union from typing import List, Union
import discord import discord
from colorama import Fore, Style, init
from discord.ext import commands from discord.ext import commands
from rich.traceback import install
from . import Config from . import Config
from .data_manager import logs_data_path from .data_manager import logs_data_path
from .utils.functions.cli import bordered from .utils.functions.cli import bordered
from . import __version__ from . import __version__, ExitCodes
from .utils.functions.extra import ContextPlus from .utils.functions.extra import ContextPlus
log = logging.getLogger("tuxbot") log = logging.getLogger("tuxbot")
init() install()
NAME = r""" NAME = r"""
_____ _ _ _ _ _____ _ _ _ _
@ -192,9 +194,3 @@ class Tux(commands.AutoShardedBot):
await self.logout() await self.logout()
sys.exit(self.shutdown_code) sys.exit(self.shutdown_code)
class ExitCodes:
CRITICAL = 1
SHUTDOWN = 0
RESTART = 42

View file

@ -33,10 +33,12 @@ def init_logging(level: int, location: pathlib.Path) -> None:
) )
dpy_handler = logging.handlers.RotatingFileHandler( dpy_handler = logging.handlers.RotatingFileHandler(
str(dpy_logger_file.resolve()), maxBytes=MAX_BYTES, backupCount=MAX_OLD_LOGS str(dpy_logger_file.resolve()),
maxBytes=MAX_BYTES, backupCount=MAX_OLD_LOGS
) )
base_handler = logging.handlers.RotatingFileHandler( base_handler = logging.handlers.RotatingFileHandler(
str(base_logger_file.resolve()), maxBytes=MAX_BYTES, backupCount=MAX_OLD_LOGS str(base_logger_file.resolve()),
maxBytes=MAX_BYTES, backupCount=MAX_OLD_LOGS
) )
stdout_handler = logging.StreamHandler(sys.stdout) stdout_handler = logging.StreamHandler(sys.stdout)

View file

@ -8,12 +8,14 @@ from typing import NoReturn, Union, List
from rich.prompt import Prompt, IntPrompt from rich.prompt import Prompt, IntPrompt
from rich.console import Console from rich.console import Console
from rich.rule import Rule from rich.rule import Rule
from rich.traceback import install
from rich import print from rich import print
from tuxbot.core.data_manager import config_dir, app_dir from tuxbot.core.data_manager import config_dir, app_dir
console = Console() console = Console()
console.clear() console.clear()
install(console=console)
try: try:
config_dir.mkdir(parents=True, exist_ok=True) config_dir.mkdir(parents=True, exist_ok=True)
@ -337,7 +339,6 @@ def basic_setup() -> NoReturn:
) )
) )
print() print()
name = get_name() name = get_name()
data_dir = get_data_dir(name) data_dir = get_data_dir(name)
@ -392,6 +393,8 @@ def setup() -> NoReturn:
basic_setup() basic_setup()
except KeyboardInterrupt: except KeyboardInterrupt:
print("Exiting...") print("Exiting...")
except:
console.print_exception()
if __name__ == "__main__": if __name__ == "__main__":