From 6d8f6201acbada682c6a69738a839b79dc59aa10 Mon Sep 17 00:00:00 2001 From: Bart Feenstra Date: Tue, 6 Dec 2022 18:31:30 +0000 Subject: [PATCH] Add system reports. (#932) --- betty/about.py | 27 +++++++++++ betty/assets/betty.pot | 7 ++- .../assets/locale/fr_FR/LC_MESSAGES/betty.po | 7 ++- .../assets/locale/nl_NL/LC_MESSAGES/betty.po | 9 ++-- betty/assets/locale/uk/LC_MESSAGES/betty.po | 7 ++- betty/cli.py | 2 +- betty/gui/app.py | 47 ++++++++++++++++--- 7 files changed, 90 insertions(+), 16 deletions(-) diff --git a/betty/about.py b/betty/about.py index 3548f1e35..f2191901f 100644 --- a/betty/about.py +++ b/betty/about.py @@ -1,4 +1,8 @@ +import platform +import sys +from importlib.metadata import distributions from pathlib import Path +from typing import Dict, Iterator def version() -> str: @@ -7,3 +11,26 @@ def version() -> str: if release_version == '0.0.0': return 'development' return release_version + + +def _indent_mapping(items: Dict[str, str]) -> str: + max_indentation = max(map(len, items.keys())) + 4 + return '\n'.join(map(lambda x: '\n'.join(_indent_mapping_item(x[0], x[1], max_indentation)), items.items())) + + +def _indent_mapping_item(key: str, value: str, max_indentation: int) -> Iterator[str]: + lines = value.split('\n') + yield f'{key}{" " * (max_indentation - len(key))} {lines[0]}' + for line in lines[1:]: + yield f'{" " * max_indentation} {line}' + + +def report() -> str: + return _indent_mapping({ + 'Betty': version(), + 'Operating system': platform.platform(), + 'Python': sys.version, + 'Python packages': _indent_mapping({ + x.metadata["Name"]: x.version for x in sorted(distributions(), key=lambda x: x.metadata["Name"].lower()) + }), + }) diff --git a/betty/assets/betty.pot b/betty/assets/betty.pot index a52dd3571..fb0d232fe 100644 --- a/betty/assets/betty.pot +++ b/betty/assets/betty.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Betty VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-11-17 13:48+0000\n" +"POT-Creation-Date: 2022-12-06 18:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -602,7 +602,10 @@ msgstr "" msgid "Remove people, events, places, files, sources, and citations if they have no relationships with any other resources. Enable the Privatizer and Anonymizer as well to make this most effective." msgstr "" -msgid "Report bugs and request new features" +msgid "Report a bug" +msgstr "" + +msgid "Request a new feature" msgstr "" msgid "Reset" diff --git a/betty/assets/locale/fr_FR/LC_MESSAGES/betty.po b/betty/assets/locale/fr_FR/LC_MESSAGES/betty.po index 976ca301a..94627675c 100644 --- a/betty/assets/locale/fr_FR/LC_MESSAGES/betty.po +++ b/betty/assets/locale/fr_FR/LC_MESSAGES/betty.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-11-17 13:48+0000\n" +"POT-Creation-Date: 2022-12-06 18:11+0000\n" "PO-Revision-Date: 2020-11-27 19:49+0100\n" "Last-Translator: \n" "Language: fr\n" @@ -684,7 +684,10 @@ msgid "" "Anonymizer as well to make this most effective." msgstr "" -msgid "Report bugs and request new features" +msgid "Report a bug" +msgstr "" + +msgid "Request a new feature" msgstr "" msgid "Reset" diff --git a/betty/assets/locale/nl_NL/LC_MESSAGES/betty.po b/betty/assets/locale/nl_NL/LC_MESSAGES/betty.po index 28f2831a3..3fb60668a 100644 --- a/betty/assets/locale/nl_NL/LC_MESSAGES/betty.po +++ b/betty/assets/locale/nl_NL/LC_MESSAGES/betty.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-11-17 13:48+0000\n" +"POT-Creation-Date: 2022-12-06 18:11+0000\n" "PO-Revision-Date: 2022-04-08 01:58+0100\n" "Last-Translator: \n" "Language: nl\n" @@ -719,8 +719,11 @@ msgstr "" "Schakel de Privatiseerder en Anonimiseerder in om dit zo effectief " "mogelijk te maken." -msgid "Report bugs and request new features" -msgstr "Meld problemen en vraag nieuwe functionaliteit aan" +msgid "Report a bug" +msgstr "Meld een probleem" + +msgid "Request a new feature" +msgstr "Vraag nieuwe functionaliteit aan" msgid "Reset" msgstr "Reset" diff --git a/betty/assets/locale/uk/LC_MESSAGES/betty.po b/betty/assets/locale/uk/LC_MESSAGES/betty.po index 2263ecc93..afad1de62 100644 --- a/betty/assets/locale/uk/LC_MESSAGES/betty.po +++ b/betty/assets/locale/uk/LC_MESSAGES/betty.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Betty VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-11-17 13:48+0000\n" +"POT-Creation-Date: 2022-12-06 18:11+0000\n" "PO-Revision-Date: 2020-05-02 22:29+0100\n" "Last-Translator: FULL NAME \n" "Language: uk\n" @@ -676,7 +676,10 @@ msgid "" "Anonymizer as well to make this most effective." msgstr "" -msgid "Report bugs and request new features" +msgid "Report a bug" +msgstr "" + +msgid "Request a new feature" msgstr "" msgid "Reset" diff --git a/betty/cli.py b/betty/cli.py index 1b6e094ca..176629da2 100644 --- a/betty/cli.py +++ b/betty/cli.py @@ -127,7 +127,7 @@ def get_command(self, ctx: Context, cmd_name: str): @click.command(cls=_BettyCommands) @click.option('--configuration', '-c', 'app', is_eager=True, help='The path to a Betty project configuration file. Defaults to betty.json|yaml|yml in the current working directory. This will make additional commands available.', callback=_init_ctx) -@click.version_option(about.version(), prog_name='Betty') +@click.version_option(about.version(), message=about.report(), prog_name='Betty') def main(app): pass diff --git a/betty/gui/app.py b/betty/gui/app.py index 1325489d2..4075dadde 100644 --- a/betty/gui/app.py +++ b/betty/gui/app.py @@ -2,12 +2,14 @@ from datetime import datetime from os import path from typing import TYPE_CHECKING +from urllib.parse import urlencode from PyQt6.QtCore import Qt, QCoreApplication from PyQt6.QtGui import QIcon, QAction from PyQt6.QtWidgets import QFormLayout, QWidget, QVBoxLayout, QHBoxLayout, QFileDialog, QPushButton from betty import about, cache +from betty.about import report from betty.asyncio import sync from betty.gui import BettyWindow, get_configuration_file_filter from betty.gui.error import catch_exceptions @@ -58,9 +60,13 @@ def __init__(self, *args, **kwargs): self.help_menu = menu_bar.addMenu('') - self.view_issues_action = QAction(self) - self.view_issues_action.triggered.connect(lambda _: self.view_issues()) # type: ignore - self.help_menu.addAction(self.view_issues_action) + self.report_bug_action = QAction(self) + self.report_bug_action.triggered.connect(lambda _: self.report_bug()) # type: ignore + self.help_menu.addAction(self.report_bug_action) + + self.request_feature_action = QAction(self) + self.request_feature_action.triggered.connect(lambda _: self.request_feature()) # type: ignore + self.help_menu.addAction(self.request_feature_action) self.about_action = QAction(self) self.about_action.triggered.connect(lambda _: self._about_betty()) # type: ignore @@ -79,12 +85,41 @@ def _do_set_translatables(self) -> None: self.clear_caches_action.setText(_('Clear all caches')) self.exit_action.setText(_('Exit')) self.help_menu.setTitle('&' + _('Help')) - self.view_issues_action.setText(_('Report bugs and request new features')) + self.report_bug_action.setText(_('Report a bug')) + self.request_feature_action.setText(_('Request a new feature')) self.about_action.setText(_('About Betty')) @catch_exceptions - def view_issues(self) -> None: - webbrowser.open_new_tab('https://github.com/bartfeenstra/betty/issues') + def report_bug(self) -> None: + body = f''' +## Summary + +## Steps to reproduce + +## Expected behavior + +## System report +``` +{report()} +``` +'''.strip() + webbrowser.open_new_tab('https://github.com/bartfeenstra/betty/issues/new?' + urlencode({ + 'body': body, + 'labels': 'bug', + })) + + @catch_exceptions + def request_feature(self) -> None: + body = ''' +## Summary + +## Expected behavior + +'''.strip() + webbrowser.open_new_tab('https://github.com/bartfeenstra/betty/issues/new?' + urlencode({ + 'body': body, + 'labels': 'enhancement', + })) @catch_exceptions def _about_betty(self) -> None: