diff --git a/.flake8 b/.flake8 index ac93b71e..8d012648 100644 --- a/.flake8 +++ b/.flake8 @@ -1,4 +1,4 @@ [flake8] -exclude=build,tests,tmp,venv,toot/tui/scroll.py +exclude=build,tests,tmp,venv,_env,toot/tui/scroll.py ignore=E128,W503,W504 max-line-length=120 diff --git a/toot/cli/__init__.py b/toot/cli/__init__.py index a4698ff9..f5258410 100644 --- a/toot/cli/__init__.py +++ b/toot/cli/__init__.py @@ -173,6 +173,7 @@ def cli(ctx: click.Context, max_width: int, color: bool, debug: bool, as_user: s from toot.cli import accounts # noqa from toot.cli import auth # noqa +from toot.cli import diag # noqa from toot.cli import lists # noqa from toot.cli import post # noqa from toot.cli import read # noqa diff --git a/toot/cli/diag.py b/toot/cli/diag.py new file mode 100644 index 00000000..0cbdc230 --- /dev/null +++ b/toot/cli/diag.py @@ -0,0 +1,29 @@ +import click +from toot import api +from toot.output import print_diags +from toot.cli import ( + cli, + pass_context, + Context, +) + + +@cli.command() +@click.option( + "-f", + "--files", + is_flag=True, + help="Print contents of the config and settings files in diagnostic output", +) +@click.option( + "-s", + "--server", + is_flag=True, + help="Print information about the curren server in diagnostic output", +) +@pass_context +def diag(ctx: Context, files: bool, server: bool): + """Display useful information for diagnosing problems""" + + instance_dict = api.get_instance(ctx.app.base_url).json() if server else None + print_diags(instance_dict, files) diff --git a/toot/output.py b/toot/output.py index e9b08120..1fae12e0 100644 --- a/toot/output.py +++ b/toot/output.py @@ -314,6 +314,84 @@ def format_account_name(account: Account) -> str: return acct +def print_diags(instance_dict: t.Dict, include_files: bool): + from importlib.metadata import version + + click.echo(f'{green(f"Diagnostic Information")}') + from datetime import datetime, timezone + + now = datetime.now(timezone.utc) + click.echo(f'{green("Current Date/Time:")} {now.strftime("%Y-%m-%d %H:%M:%S %Z")}') + + from toot import __version__, config, settings + click.echo(f'{green(f"Toot version:")} {__version__}') + + import platform + click.echo(f'{green(f"Platform:")} {platform.platform()}') + + # print distro - only call if available (python 3.10+) + fd_os_release = getattr(platform, "freedesktop_os_release", None) # novermin + if callable(fd_os_release): # novermin + try: + name = platform.freedesktop_os_release()['PRETTY_NAME'] + click.echo(f'{green(f"Distro:")} {name}') + except: # noqa + pass + + click.echo(f'{green(f"Python version:")} {platform.python_version()}') + click.echo(green("Dependency versions:")) + + deps = sorted(['beautifulsoup4', 'click', 'requests', 'tomlkit', 'urwid', 'wcwidth', + 'pillow', 'term-image', 'urwidgets', 'flake8', 'pytest', 'setuptools', + 'vermin', 'typing-extensions']) + + for dep in deps: + try: + ver = version(dep) + except: # noqa + ver = yellow("not installed") + + click.echo(f"\t{dep}: {ver}") + + click.echo(f'{green(f"Settings file path:")} {settings.get_settings_path()}') + click.echo(f'{green(f"Config file path:")} {config.get_config_file_path()}') + + if instance_dict: + try: + click.echo(f'{green(f"Server URI:")} {instance_dict["uri"]}') + except: # noqa E722 + pass + try: + click.echo(f'{green(f"Server version:")} {instance_dict["version"]}') + except: # noqa E722 + pass + + if include_files: + click.echo(f'{green(f"Settings file contents:")}') + try: + with open(settings.get_settings_path(), 'r') as f: + print(f.read()) + except: # noqa + click.echo(f'{yellow(f"Could not open settings file")}') + + click.echo('') + + click.echo(f'{green(f"Config file contents:")}') + try: + with open(config.get_config_file_path(), 'r') as f: + for line in f: + # Do not output client secret or access token lines + if "client_" in line or "token" in line: + click.echo(f'{yellow("***CONTENTS REDACTED***")}') + else: + click.echo(line, nl=False) + + except: # noqa + click.echo(f'{yellow(f"Could not open config file")}') + + click.echo('') + + # Shorthand functions for coloring output def blue(text: t.Any) -> str: