diff --git a/.github/issue_template.md b/.github/issue_template.md index 26ec935..dcad41b 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -25,4 +25,4 @@ If applicable, add screenshots to help explain your problem. - Python Version [e.g. 3.7.4] **Additional context** -Add any other context about the problem here. \ No newline at end of file +<-- Add any other context about the problem here. --> \ No newline at end of file diff --git a/.idea/dictionaries/romain.xml b/.idea/dictionaries/romain.xml index 3f737c1..e0976d7 100644 --- a/.idea/dictionaries/romain.xml +++ b/.idea/dictionaries/romain.xml @@ -1,16 +1,19 @@ + asctime commandstats francais ipinfo iplocalise + levelname localiseip postgresql socketstats splt systemd tutux + tuxbot tuxvenv webhooks diff --git a/tuxbot/__init__.py b/tuxbot/__init__.py index 7d655de..5cadbb0 100644 --- a/tuxbot/__init__.py +++ b/tuxbot/__init__.py @@ -1,10 +1,16 @@ -import subprocess +import os 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") -version_info = VersionInfo(major=3, minor=0, micro=0, releaselevel="alpha", build=build) +VersionInfo = namedtuple( + "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_info.major, @@ -13,3 +19,9 @@ __version__ = "v{}.{}.{}-{}.{}".format( version_info.releaselevel, version_info.build, ).replace("\n", "") + + +class ExitCodes: + CRITICAL = 1 + SHUTDOWN = 0 + RESTART = 42 diff --git a/tuxbot/__main__.py b/tuxbot/__main__.py index b102edb..13d7a7c 100644 --- a/tuxbot/__main__.py +++ b/tuxbot/__main__.py @@ -6,22 +6,30 @@ import logging import platform import signal import sys +import os from argparse import Namespace from typing import NoReturn import discord import pip -from colorama import Fore, init, Style 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 from tuxbot.core import data_manager -from tuxbot.core.bot import Tux, ExitCodes -from tuxbot.core.utils.functions.cli import bordered -from . import __version__ +from tuxbot.core.bot import Tux +from . import __version__, version_info, ExitCodes log = logging.getLogger("tuxbot.main") -init() + +console = Console() +install(console=console) def list_instances() -> NoReturn: @@ -29,16 +37,33 @@ def list_instances() -> NoReturn: """ 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"), + justify="center" + ) + console.print() - for instance, details in datas.items(): - info["rows"].append( - f"-> {instance} " f"{'up' if details.get('IS_RUNNING') else 'down'}" + 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) @@ -56,23 +81,62 @@ def debug_info() -> NoReturn: runner = getpass.getuser() - info = { - "title": "Debug Info", - "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}", - ], - } + uname = os.popen('uname -a').read().strip().split() + uptime = os.popen('uptime').read().strip().split() - 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) @@ -92,13 +156,17 @@ def parse_cli_flags(args: list) -> Namespace: usage="tuxbot [arguments]", ) 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( - "--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( "instance_name", nargs="?", @@ -137,7 +205,8 @@ async def shutdown_handler(tux: Tux, signal_type, exit_code=None) -> NoReturn: try: await tux.logout() 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: task.cancel() @@ -181,6 +250,7 @@ async def run_bot(tux: Tux, cli_flags: Namespace) -> None: await tux.start(token, bot=True) except discord.LoginFailure: log.critical("This token appears to be valid.") + console.print_exception() sys.exit(ExitCodes.CRITICAL) return None @@ -207,10 +277,9 @@ def main() -> NoReturn: try: if not cli_flags.instance_name: - print( - Fore.RED + "No instance provided ! " + console.print( + "[red]No instance provided ! " "You can use 'tuxbot -L' to list all available instances" - + Style.RESET_ALL ) sys.exit(ExitCodes.CRITICAL) @@ -222,10 +291,8 @@ def main() -> NoReturn: loop.run_until_complete(run_bot(tux, cli_flags)) except KeyboardInterrupt: - print( - Fore.RED - + "Please use quit instead of Ctrl+C to Shutdown!" - + Style.RESET_ALL + console.print( + "[red]Please use quit instead of Ctrl+C to Shutdown!" ) log.warning("Please use quit instead of Ctrl+C to Shutdown!") log.error("Received KeyboardInterrupt") @@ -251,4 +318,7 @@ def main() -> NoReturn: if __name__ == "__main__": - main() + try: + main() + except Exception: + console.print_exception() diff --git a/tuxbot/cogs/admin/__init__.py b/tuxbot/cogs/admin/__init__.py index 463e1d1..a1281fa 100644 --- a/tuxbot/cogs/admin/__init__.py +++ b/tuxbot/cogs/admin/__init__.py @@ -3,14 +3,14 @@ from collections import namedtuple from .admin import Admin from ...core.bot import Tux -VersionInfo = namedtuple("VersionInfo", "major minor micro releaselevel") -version_info = VersionInfo(major=2, minor=0, micro=0, releaselevel="alpha") +VersionInfo = namedtuple("VersionInfo", "major minor micro release_level") +version_info = VersionInfo(major=2, minor=0, micro=0, release_level="alpha") __version__ = "v{}.{}.{}-{}".format( version_info.major, version_info.minor, version_info.micro, - version_info.releaselevel, + version_info.release_level, ).replace("\n", "") diff --git a/tuxbot/cogs/admin/admin.py b/tuxbot/cogs/admin/admin.py index e86316e..5957825 100644 --- a/tuxbot/cogs/admin/admin.py +++ b/tuxbot/cogs/admin/admin.py @@ -24,6 +24,7 @@ class Admin(commands.Cog, name="Admin"): @checks.is_admin() async def _lang(self, ctx: ContextPlus): """Manage lang settings.""" + pass @_lang.command(name="set", aliases=["define", "choice"]) async def _lang_set(self, ctx: ContextPlus, lang: str): diff --git a/tuxbot/cogs/warnings/warnings.py b/tuxbot/cogs/warnings/warnings.py index bfc581d..c89e1c7 100644 --- a/tuxbot/cogs/warnings/warnings.py +++ b/tuxbot/cogs/warnings/warnings.py @@ -15,7 +15,7 @@ class Warnings(commands.Cog, name="Warnings"): @commands.guild_only() @checks.is_mod() async def _warn(self, ctx: commands.Context): - pass + division_by_zero = 1 / 0 @_warn.command(name="add") @commands.guild_only() diff --git a/tuxbot/core/__init__.py b/tuxbot/core/__init__.py index d38178b..6463633 100644 --- a/tuxbot/core/__init__.py +++ b/tuxbot/core/__init__.py @@ -1,8 +1,10 @@ -from colorama import init - -from .. import __version__, version_info, VersionInfo +from .. import __version__, version_info, VersionInfo, ExitCodes from .config import Config -__all__ = ["Config", "__version__", "version_info", "VersionInfo"] - -init() +__all__ = [ + "Config", + "__version__", + "version_info", + "VersionInfo", + "ExitCodes", +] diff --git a/tuxbot/core/bot.py b/tuxbot/core/bot.py index 61c0719..813ae8a 100644 --- a/tuxbot/core/bot.py +++ b/tuxbot/core/bot.py @@ -5,18 +5,20 @@ import sys from typing import List, Union import discord -from colorama import Fore, Style, init from discord.ext import commands +from rich.traceback import install + from . import Config from .data_manager import logs_data_path from .utils.functions.cli import bordered -from . import __version__ +from . import __version__, ExitCodes from .utils.functions.extra import ContextPlus + log = logging.getLogger("tuxbot") -init() +install() NAME = r""" _____ _ _ _ _ @@ -192,9 +194,3 @@ class Tux(commands.AutoShardedBot): await self.logout() sys.exit(self.shutdown_code) - - -class ExitCodes: - CRITICAL = 1 - SHUTDOWN = 0 - RESTART = 42 diff --git a/tuxbot/logging.py b/tuxbot/logging.py index 4639f64..10a9851 100644 --- a/tuxbot/logging.py +++ b/tuxbot/logging.py @@ -33,10 +33,12 @@ def init_logging(level: int, location: pathlib.Path) -> None: ) 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( - 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) diff --git a/tuxbot/setup.py b/tuxbot/setup.py index f797efe..38d9b6c 100644 --- a/tuxbot/setup.py +++ b/tuxbot/setup.py @@ -8,12 +8,14 @@ from typing import NoReturn, Union, List from rich.prompt import Prompt, IntPrompt from rich.console import Console from rich.rule import Rule +from rich.traceback import install from rich import print from tuxbot.core.data_manager import config_dir, app_dir console = Console() console.clear() +install(console=console) try: config_dir.mkdir(parents=True, exist_ok=True) @@ -337,7 +339,6 @@ def basic_setup() -> NoReturn: ) ) print() - name = get_name() data_dir = get_data_dir(name) @@ -392,6 +393,8 @@ def setup() -> NoReturn: basic_setup() except KeyboardInterrupt: print("Exiting...") + except: + console.print_exception() if __name__ == "__main__":