This commit is contained in:
Mykola Grymalyuk
2023-04-13 07:25:54 -06:00
8 changed files with 222 additions and 4 deletions
+97
View File
@@ -0,0 +1,97 @@
import datetime
import plistlib
from pathlib import Path
import json
from resources import network_handler, constants, global_settings
DATE_FORMAT: str = "%Y-%m-%d %H-%M-%S"
ANALYTICS_SERVER: str = ""
SITE_KEY: str = ""
VALID_ENTRIES: dict = {
'KEY': str, # Prevent abuse (embedded at compile time)
'UNIQUE_IDENTITY': str, # Host's UUID as SHA1 hash
'APPLICATION_NAME': str, # ex. OpenCore Legacy Patcher
'APPLICATION_VERSION': str, # ex. 0.2.0
'OS_VERSION': str, # ex. 10.15.7
'MODEL': str, # ex. MacBookPro11,5
'GPUS': list, # ex. ['Intel Iris Pro', 'AMD Radeon R9 M370X']
'FIRMWARE': str, # ex. APPLE
'LOCATION': str, # ex. 'US' (just broad region, don't need to be specific)
'TIMESTAMP': datetime.datetime, # ex. 2021-09-01-12-00-00
}
class Analytics:
def __init__(self, global_constants: constants.Constants) -> None:
self.constants: constants.Constants = global_constants
if global_settings.GlobalEnviromentSettings().read_property("DisableCrashAndAnalyticsReporting") is True:
return
self._generate_base_data()
self._post_data()
def _get_country(self) -> str:
# Get approximate country from .GlobalPreferences.plist
path = "/Library/Preferences/.GlobalPreferences.plist"
if not Path(path).exists():
return "US"
try:
result = plistlib.load(Path(path).open("rb"))
except:
return "US"
if "Country" not in result:
return "US"
return result["Country"]
def _generate_base_data(self) -> None:
self.unique_identity = str(self.constants.computer.uuid_sha1)
self.application = str("OpenCore Legacy Patcher")
self.version = str(self.constants.patcher_version)
self.os = str( self.constants.detected_os_version)
self.model = str(self.constants.computer.real_model)
self.gpus = []
self.firmware = str(self.constants.computer.firmware_vendor)
self.location = str(self._get_country())
for gpu in self.constants.computer.gpus:
self.gpus.append(str(gpu.arch))
self.data = {
'KEY': SITE_KEY,
'UNIQUE_IDENTITY': self.unique_identity,
'APPLICATION_NAME': self.application,
'APPLICATION_VERSION': self.version,
'OS_VERSION': self.os,
'MODEL': self.model,
'GPUS': self.gpus,
'FIRMWARE': self.firmware,
'LOCATION': self.location,
'TIMESTAMP': str(datetime.datetime.now().strftime(DATE_FORMAT)),
}
# convert to JSON:
self.data = json.dumps(self.data)
def _post_data(self) -> None:
# Post data to analytics server
if ANALYTICS_SERVER == "":
return
if SITE_KEY == "":
return
network_handler.NetworkUtilities().post(ANALYTICS_SERVER, json = self.data)
+4
View File
@@ -6,6 +6,7 @@ import enum
import itertools
import subprocess
import plistlib
import hashlib
from pathlib import Path
from dataclasses import dataclass, field
from typing import Any, ClassVar, Optional, Type, Union
@@ -491,6 +492,7 @@ class Computer:
reported_model: Optional[str] = None
reported_board_id: Optional[str] = None
build_model: Optional[str] = None
uuid_sha1: Optional[str] = None
gpus: list[GPU] = field(default_factory=list)
igpu: Optional[GPU] = None # Shortcut for IGPU
dgpu: Optional[GPU] = None # Shortcut for GFX0
@@ -719,6 +721,8 @@ class Computer:
else:
board = "board-id"
self.reported_board_id = ioreg.corefoundation_to_native(ioreg.IORegistryEntryCreateCFProperty(entry, board, ioreg.kCFAllocatorDefault, ioreg.kNilOptions)).strip(b"\0").decode() # type: ignore
self.uuid_sha1 = ioreg.corefoundation_to_native(ioreg.IORegistryEntryCreateCFProperty(entry, "IOPlatformUUID", ioreg.kCFAllocatorDefault, ioreg.kNilOptions)) # type: ignore
self.uuid_sha1 = hashlib.sha1(self.uuid_sha1.encode()).hexdigest()
ioreg.IOObjectRelease(entry)
# Real model
+16 -2
View File
@@ -2980,12 +2980,23 @@ class wx_python_gui:
self.delete_unused_kdks_checkbox.GetPosition().y + self.delete_unused_kdks_checkbox.GetSize().height))
self.set_ignore_app_updates_checkbox.SetToolTip(wx.ToolTip("This will set whether OpenCore will ignore App Updates on launch.\nEnable this option if you do not want to be prompted for App Updates"))
# Set Disable Analytics
res = global_settings.GlobalEnviromentSettings().read_property("DisableCrashAndAnalyticsReporting")
res = False if res is None else res
self.set_disable_analytics_checkbox = wx.CheckBox(self.frame_modal, label="Disable Crash/Analytics")
self.set_disable_analytics_checkbox.SetValue(res)
self.set_disable_analytics_checkbox.Bind(wx.EVT_CHECKBOX, self.set_disable_analytics_click)
self.set_disable_analytics_checkbox.SetPosition(wx.Point(
self.set_ignore_app_updates_checkbox.GetPosition().x,
self.set_ignore_app_updates_checkbox.GetPosition().y + self.set_ignore_app_updates_checkbox.GetSize().height))
self.set_disable_analytics_checkbox.SetToolTip(wx.ToolTip("Sets whether anonymized analytics are sent to the Dortania team.\nThis is used to help improve the application and is completely optional."))
# Button: Developer Debug Info
self.debug_button = wx.Button(self.frame_modal, label="Developer Debug Info")
self.debug_button.Bind(wx.EVT_BUTTON, self.additional_info_menu)
self.debug_button.SetPosition(wx.Point(
self.set_ignore_app_updates_checkbox.GetPosition().x,
self.set_ignore_app_updates_checkbox.GetPosition().y + self.set_ignore_app_updates_checkbox.GetSize().height + 5))
self.set_disable_analytics_checkbox.GetPosition().x,
self.set_disable_analytics_checkbox.GetPosition().y + self.set_disable_analytics_checkbox.GetSize().height + 5))
self.debug_button.Center(wx.HORIZONTAL)
# Button: return to main menu
@@ -3038,6 +3049,9 @@ class wx_python_gui:
else:
global_settings.GlobalEnviromentSettings().write_property("IgnoreAppUpdates", False)
def set_disable_analytics_click(self, event):
global_settings.GlobalEnviromentSettings().write_property("DisableCrashAndAnalyticsReporting", self.set_disable_analytics_checkbox.GetValue())
def firewire_click(self, event=None):
if self.firewire_boot_checkbox.GetValue():
logging.info("Firewire Enabled")
+3 -1
View File
@@ -16,7 +16,8 @@ from resources import (
arguments,
reroute_payloads,
commit_info,
logging_handler
logging_handler,
analytics_handler,
)
@@ -89,6 +90,7 @@ class OpenCoreLegacyPatcher:
# Generate defaults
defaults.GenerateDefaults(self.computer.real_model, True, self.constants)
threading.Thread(target=analytics_handler.Analytics, args=(self.constants,)).start()
if utilities.check_cli_args() is None:
logging.info(f"- No arguments present, loading {'GUI' if self.constants.wxpython_variant is True else 'TUI'} mode")