Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[806] Add System Profiler Utility #2224

Merged
merged 7 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,19 @@ assignees: ''

---

**Please check the [Known Issues](https://github.com/EDCD/EDMarketConnector/issues/618) in case this has already been reported.**

**Please also check if the issue is covered in our [Troubleshooting Guide](https://github.com/EDCD/EDMarketConnector/wiki/Troubleshooting).** It might be something with a known work around, or where a third party (such as EDSM) is causing logging that is harmless.

**Please complete the following information:**
- Version: [e.g. 4.0.6 - See 'Help > About E:D Market Connector'. If running from source using git then please paste the output of `git log --decorate=full | head -1`]

[//]: # (You can gather most of this information with the EDMC System Profiler)

- Version: [e.g. 5.10.4+39af6c34`]
- Game Version: [e.g. 'Live' or 'Odyssey']
- OS: [e.g. Windows 10, Linux Debian 10.6, etc.]
- OS Locale: [e.g. English, French, Serbian...]
- If applicable: Browser [e.g. chrome, safari]
- Please attach **BOTH** log files, by dragging and dropping them into this input:
1. `%TEMP%\EDMarketConnector.log` from *immediately* after the bug occurs (re-running the application overwrites this file).
1. `%TEMP%\EDMarketConnector\EDMarketConnector-debug.log`. See [Debug Log File](https://github.com/EDCD/EDMarketConnector/wiki/Troubleshooting#debug-log-files). NB: If you don't have this log file then you're not running the latest version of the application and should update first to see if we already fixed the bug you're reporting.

**Describe the bug**
A clear and concise description of what the bug is.

[//]: # (A clear and concise description of what the bug is.)

**To Reproduce**
Steps to reproduce the behavior:
Expand All @@ -32,10 +29,24 @@ Steps to reproduce the behavior:
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

[//]: # (A clear and concise description of what you expected to happen.)

**Screenshots**
If applicable, add screenshots to help explain your problem.

[//]: # (If applicable, add screenshots to help explain your problem.)

**Additional context**
Add any other context about the problem here.

**Please Confirm the Following...**

[//]: # (Add any other context about the problem here.)
- [ ] I have checked the [Known Issues](https://github.com/EDCD/EDMarketConnector/issues/618) list to ensure this is not a duplicate
- [ ] I have checked the [Troubleshooting Guide](https://github.com/EDCD/EDMarketConnector/wiki/Troubleshooting) to check for known workarounds

**Logs**
Please attach both the EDMarketConnector.log and EDMarketConnector-debug.log if available.

You can find these logs at `%TEMP%\EDMarketConnector.log` and `%TEMP%\EDMarketConnector\EDMarketConnector-debug.log`

See [Debug Log File](https://github.com/EDCD/EDMarketConnector/wiki/Troubleshooting#debug-log-files) for information on the Debug Log files
206 changes: 206 additions & 0 deletions EDMCSystemProfiler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#!/usr/bin/env python3
"""
EDMCSystemProfiler.py - GUI or Command-Line Tool to Print Diagnostic Information about EDMC.

Copyright (c) EDCD, All Rights Reserved
Licensed under the GNU General Public License.
See LICENSE file.
"""
import argparse
import locale
import webbrowser
import platform
import sys
from os import chdir, environ, path
import pathlib
import logging
from journal_lock import JournalLock

if getattr(sys, "frozen", False):
# Under py2exe sys.path[0] is the executable name
if sys.platform == "win32":
chdir(path.dirname(sys.path[0]))
# Allow executable to be invoked from any cwd
environ["TCL_LIBRARY"] = path.join(path.dirname(sys.path[0]), "lib", "tcl")
environ["TK_LIBRARY"] = path.join(path.dirname(sys.path[0]), "lib", "tk")

else:
# We still want to *try* to have CWD be where the main script is, even if
# not frozen.
chdir(pathlib.Path(__file__).parent)

import config
from config import appversion, appname
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from monitor import monitor
from EDMCLogging import get_main_logger


def get_sys_report(config: config.AbstractConfig) -> str:
"""Gather system information about Elite, the Host Computer, and EDMC."""
# Calculate Requested Information
plt = platform.uname()
locale.setlocale(locale.LC_ALL, "")
lcl = locale.getlocale()
monitor.currentdir = config.get_str(
"journaldir", default=config.default_journal_dir
)
if not monitor.currentdir:
monitor.currentdir = config.default_journal_dir
try:
logfile = monitor.journal_newest_filename(monitor.currentdir)
if logfile is None:
raise ValueError("None from monitor.journal_newest_filename")

with open(logfile, "rb", 0) as loghandle:
for line in loghandle:
try:
monitor.parse_entry(line)
except Exception as e:
exception_type = e.__class__.__name__
monitor.state["GameVersion"] = (
exception_type
if not monitor.state["GameVersion"]
else monitor.state["GameVersion"]
)
monitor.state["GameBuild"] = (
exception_type
if not monitor.state["GameBuild"]
else monitor.state["GameBuild"]
)
monitor.state["Odyssey"] = (
exception_type
if not monitor.state["Odyssey"]
else monitor.state["Odyssey"]
)
except Exception as e:
exception_type = e.__class__.__name__
monitor.state["GameVersion"] = exception_type
monitor.state["GameBuild"] = exception_type
monitor.state["Odyssey"] = exception_type

journal_lock = JournalLock()
lockable = journal_lock.open_journal_dir_lockfile()

report = f"EDMC Version: \n - {appversion()}\n\n"
report += "OS Details:\n"
report += f"- Operating System: {plt.system} {plt.release}\n"
report += f"- Version: {plt.version}\n"
report += f"- Machine: {plt.machine}\n"
report += f"- Python Version: {platform.python_version()}\n"
report += "\nEnvironment Details\n"
report += f"- Detected Locale: {lcl[0]}\n"
report += f"- Detected Encoding: {lcl[1]}\n"
report += f"- Journal Directory: {monitor.currentdir}\n"
report += f"- Game Version: {monitor.state['GameVersion']}\n"
report += f"- Game Build: {monitor.state['GameBuild']}\n"
report += f"- Using Odyssey: {monitor.state['Odyssey']}\n"
report += f"- Journal Dir Lockable: {lockable}\n"
return report


def copy_sys_report(root: tk.Tk, report: str) -> None:
"""Copy the system info to the keyboard."""
root.clipboard_clear()
root.clipboard_append(report)
messagebox.showinfo("System Profiler", "System Report copied to Clipboard")


def main() -> None:
"""Entry Point for the System Profiler."""
# Now Let's Begin
root: tk.Tk = tk.Tk()
root.withdraw() # Hide the window initially to calculate the dimensions
try:
icon_image = tk.PhotoImage(
file=path.join(cur_config.respath_path, "io.edcd.EDMarketConnector.png")
)

root.iconphoto(True, icon_image)
except tk.TclError:
root.iconbitmap(path.join(cur_config.respath_path, "EDMarketConnector.ico"))

sys_report = get_sys_report(cur_config)

# Set up styling
style = ttk.Style(root)
style.configure("Title.TLabel", font=("Helvetica", 10, "bold"), foreground="#333")
style.configure("Subtitle.TLabel", font=("Helvetica", 8), foreground="#555")
style.configure("Details.TLabel", font=("Helvetica", 8), foreground="#222")

# Build UI
title_lbl = ttk.Label(
root, text="EDMarketConnector System Profiler", style="Title.TLabel"
)
title_lbl.grid(row=0, column=0, padx=20, pady=10)

system_details_lbl = ttk.Label(
root, text="System Details:", style="Subtitle.TLabel"
)
system_details_lbl.grid(row=1, column=0, padx=20, pady=0, sticky="w")

details_lbl = ttk.Label(
root, text=sys_report, style="Details.TLabel", justify="left"
)
details_lbl.grid(row=2, column=0, padx=20, pady=5, sticky="w")

# Buttons
sys_report_btn = ttk.Button(
root,
text="Copy System Report",
command=lambda: copy_sys_report(root, sys_report),
)
sys_report_btn.grid(row=3, column=0, padx=20, pady=10, sticky="w")

github_btn = ttk.Button(
root,
text="Open GitHub Bug Report",
command=lambda: webbrowser.open(
"https://github.com/EDCD/EDMarketConnector/issues/new?assignees="
"&labels=bug%2C+unconfirmed&projects=&template=bug_report.md&title="
),
)
github_btn.grid(row=3, column=0, padx=20, pady=10, sticky="e")

# Update and get window dimensions
root.update()
width = root.winfo_reqwidth() + 20
height = root.winfo_reqheight() + 20

# Set window size and show
root.geometry(f"{width}x{height}")
root.title("EDMarketConnector")
root.deiconify()
root.resizable(False, False)

root.mainloop()


if __name__ == "__main__":
# Args: Only work if not frozen
parser = argparse.ArgumentParser(
prog=appname,
description="Prints diagnostic and debugging information about the current EDMC configuration.",
)
parser.add_argument(
"--out-console",
help="write the system information to the console",
action="store_true",
)
args = parser.parse_args()

# Suppress Logger
logger = get_main_logger()
logger.setLevel(logging.CRITICAL)
if getattr(sys, "frozen", False):
sys.stderr._error = "inhibit log creation" # type: ignore

cur_config = config.get_config()
if args.out_console:
sys_report = get_sys_report(cur_config)
print(sys_report)
sys.exit(0)

main()
2 changes: 2 additions & 0 deletions EDMarketConnector.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ def open_window(systray: 'SysTrayIcon') -> None:
self.help_menu.add_command(command=lambda: not self.HelpAbout.showing and self.HelpAbout(self.w))
logfile_loc = pathlib.Path(tempfile.gettempdir()) / appname
self.help_menu.add_command(command=lambda: prefs.open_folder(logfile_loc)) # Open Log Folder
self.help_menu.add_command(command=prefs.help_open_system_profiler) # Open Log Folde

self.menubar.add_cascade(menu=self.help_menu)
if sys.platform == 'win32':
Expand Down Expand Up @@ -855,6 +856,7 @@ def set_labels(self):
self.help_menu.entryconfigure(5, label=tr.tl('Check for Updates...')) # LANG: Help > Check for Updates...
self.help_menu.entryconfigure(6, label=tr.tl("About {APP}").format(APP=applongname)) # LANG: Help > About App
self.help_menu.entryconfigure(7, label=tr.tl('Open Log Folder')) # LANG: Help > Open Log Folder
self.help_menu.entryconfigure(8, label=tr.tl('Open System Profiler')) # LANG: Help > Open System Profiler

# Edit menu
self.edit_menu.entryconfigure(0, label=tr.tl('Copy')) # LANG: Label for 'Copy' as in 'Copy and Paste'
Expand Down
3 changes: 3 additions & 0 deletions L10n/en.template
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@
/* EDMarketConnector.py: Help > Check for Updates...; In files: EDMarketConnector.py:930; EDMarketConnector.py:958; */
"Check for Updates..." = "Check for Updates...";

/* EDMarketConnector.py: Help > Open System Profiler; In files: EDMarketConnector.py:888; */
"Open System Profiler" = "Open System Profiler";

/* EDMarketConnector.py: File > Save Raw Data...; In files: EDMarketConnector.py:931; EDMarketConnector.py:948; */
"Save Raw Data..." = "Save Raw Data...";

Expand Down
11 changes: 10 additions & 1 deletion build.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,19 @@ def build() -> None:
],
}

checker_config: dict = {
"dest_base": "EDMCSystemProfiler",
"script": "EDMCSystemProfiler.py",
"icon_resources": [(0, f"{appname}.ico")],
"other_resources": [
(24, 1, pathlib.Path(f"resources/{appname}.manifest").read_text(encoding="UTF8"))
],
}

try:
py2exe.freeze(
version_info=version_info,
windows=[windows_config],
windows=[windows_config, checker_config],
console=[console_config],
data_files=data_files,
options=options,
Expand Down
Binary file modified img/Balance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/UI-Athanasius-101-odyssey-docked-onfoot-cooled-down-l.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/UI-annotated.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/win.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/win_dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/win_transparent.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions prefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import contextlib
import logging
import pathlib
import subprocess
import sys
import tempfile
import tkinter as tk
Expand Down Expand Up @@ -56,6 +57,16 @@ def open_folder(file: pathlib.Path) -> None:
system(f'xdg-open "{file}"')


def help_open_system_profiler() -> None:
"""Open the EDMC System Profiler."""
profiler_path = pathlib.Path(config.respath_path)
if getattr(sys, 'frozen', False):
profiler_path /= 'EDMCSystemProfiler.exe'
subprocess.run(profiler_path)
else:
subprocess.run(['python', "EDMCSystemProfiler.py"], shell=True)


class PrefsVersion:
"""
PrefsVersion contains versioned preferences.
Expand Down
Loading