refactor settings handling to its own class
This commit is contained in:
Binary file not shown.
@@ -1,5 +1,6 @@
|
|||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk, messagebox
|
from tkinter import ttk, messagebox
|
||||||
|
from utils.settings_manager import SettingsManager
|
||||||
|
|
||||||
class AIEditorManager:
|
class AIEditorManager:
|
||||||
"""
|
"""
|
||||||
@@ -90,9 +91,9 @@ class AIEditorManager:
|
|||||||
|
|
||||||
def save_settings(self, settings):
|
def save_settings(self, settings):
|
||||||
"""Save AI copy editing settings and update the UI"""
|
"""Save AI copy editing settings and update the UI"""
|
||||||
self.app.save_settings_to_JSON(settings)
|
SettingsManager.update_settings(settings)
|
||||||
|
|
||||||
messagebox.showinfo("Settings Updated", "Your settings have been saved successfully.")
|
messagebox.showinfo("Settings Updated", "Your settings have been saved successfully.")
|
||||||
self.app.load_settings() # Refresh settings if needed elsewhere
|
|
||||||
|
|
||||||
# Update the status indicator on the main screen with more specific information
|
# Update the status indicator on the main screen with more specific information
|
||||||
self.update_status_display()
|
self.update_status_display()
|
||||||
|
|||||||
116
utils/settings_manager.py
Normal file
116
utils/settings_manager.py
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
import json
|
||||||
|
import platform
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
class SettingsManager:
|
||||||
|
"""
|
||||||
|
Centralizes access to application settings to prevent conflicts between components.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_settings_file_path(filename="settings.json"):
|
||||||
|
"""Get the platform-specific path for the settings file."""
|
||||||
|
if platform.system() == 'Darwin': # macOS
|
||||||
|
from utils.api_key_manager import APIKeyManager
|
||||||
|
mac_path = APIKeyManager.get_app_support_path_mac()
|
||||||
|
return f"{mac_path}/{filename}"
|
||||||
|
else:
|
||||||
|
return filename # Default to current directory for non-macOS systems
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_default_settings(cls):
|
||||||
|
"""Return the default settings structure."""
|
||||||
|
return {
|
||||||
|
"chat_gpt_completion": False,
|
||||||
|
"model": "gpt-4o-mini",
|
||||||
|
"prompt": "",
|
||||||
|
"auto_apply_ai_to_recording": False,
|
||||||
|
"current_tone": "None",
|
||||||
|
"hide_banner": False,
|
||||||
|
"input_device": "Default",
|
||||||
|
"primary_device": "Select Device",
|
||||||
|
"secondary_device": "None",
|
||||||
|
"hotkeys": {
|
||||||
|
"record_start_stop": ["ctrl", "shift", "0"],
|
||||||
|
"stop_recording": ["ctrl", "shift", "9"],
|
||||||
|
"play_last_audio": ["ctrl", "shift", "8"],
|
||||||
|
"cancel_operation": ["ctrl", "shift", "1"]
|
||||||
|
},
|
||||||
|
"max_tokens": 750
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_settings(cls):
|
||||||
|
"""Load settings from file, with defaults for missing values."""
|
||||||
|
settings_file = cls.get_settings_file_path()
|
||||||
|
default_settings = cls.get_default_settings()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Try to load existing settings
|
||||||
|
with open(settings_file, "r") as f:
|
||||||
|
settings = json.load(f)
|
||||||
|
|
||||||
|
# Check if settings need to be updated with new defaults
|
||||||
|
settings_updated = False
|
||||||
|
|
||||||
|
# Recursively update nested dictionaries with missing keys
|
||||||
|
def update_missing_settings(existing, defaults):
|
||||||
|
nonlocal settings_updated
|
||||||
|
for key, value in defaults.items():
|
||||||
|
if key not in existing:
|
||||||
|
existing[key] = value
|
||||||
|
settings_updated = True
|
||||||
|
elif isinstance(value, dict) and isinstance(existing[key], dict):
|
||||||
|
# Recursively update nested dictionaries
|
||||||
|
update_missing_settings(existing[key], value)
|
||||||
|
return existing
|
||||||
|
|
||||||
|
# Update settings with any missing values
|
||||||
|
settings = update_missing_settings(settings, default_settings)
|
||||||
|
|
||||||
|
# Save if any settings were updated
|
||||||
|
if settings_updated:
|
||||||
|
cls.save_settings(settings)
|
||||||
|
print("Settings file updated with new default values")
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
# Create new settings file with defaults if it doesn't exist
|
||||||
|
settings = default_settings
|
||||||
|
cls.save_settings(settings)
|
||||||
|
|
||||||
|
return settings
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def save_settings(cls, settings):
|
||||||
|
"""Save complete settings to file."""
|
||||||
|
settings_file = cls.get_settings_file_path()
|
||||||
|
|
||||||
|
with open(settings_file, "w") as f:
|
||||||
|
json.dump(settings, f)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_settings(cls, partial_settings):
|
||||||
|
"""
|
||||||
|
Update only specific settings without touching others.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
partial_settings: Dictionary containing only the settings to update
|
||||||
|
"""
|
||||||
|
# First load existing settings
|
||||||
|
current_settings = cls.load_settings()
|
||||||
|
|
||||||
|
# Update settings (recursively for nested dictionaries)
|
||||||
|
def recursive_update(target, source):
|
||||||
|
for key, value in source.items():
|
||||||
|
if isinstance(value, dict) and key in target and isinstance(target[key], dict):
|
||||||
|
# If both are dictionaries, update recursively
|
||||||
|
recursive_update(target[key], value)
|
||||||
|
else:
|
||||||
|
# Otherwise just update the value
|
||||||
|
target[key] = value
|
||||||
|
|
||||||
|
recursive_update(current_settings, partial_settings)
|
||||||
|
|
||||||
|
# Save the updated settings
|
||||||
|
cls.save_settings(current_settings)
|
||||||
|
return current_settings
|
||||||
@@ -25,6 +25,7 @@ from utils.resource_utils import ResourceUtils
|
|||||||
from utils.tone_presets_manager import TonePresetsManager
|
from utils.tone_presets_manager import TonePresetsManager
|
||||||
from utils.presets_manager import PresetsManager
|
from utils.presets_manager import PresetsManager
|
||||||
from utils.ai_editor_manager import AIEditorManager
|
from utils.ai_editor_manager import AIEditorManager
|
||||||
|
from utils.settings_manager import SettingsManager
|
||||||
|
|
||||||
# Modify the load environment variables to load from config/.env
|
# Modify the load environment variables to load from config/.env
|
||||||
def load_env_file():
|
def load_env_file():
|
||||||
@@ -1168,75 +1169,20 @@ Please also make sure you read the Terms of use and licence statement before usi
|
|||||||
print(f"Transcription error: An error occurred during transcription: {str(e)}")
|
print(f"Transcription error: An error occurred during transcription: {str(e)}")
|
||||||
|
|
||||||
def load_settings(self):
|
def load_settings(self):
|
||||||
settings_file = self.get_settings_file_path("settings.json")
|
"""Load settings using the SettingsManager."""
|
||||||
|
return SettingsManager.load_settings()
|
||||||
# Define default settings structure
|
|
||||||
default_settings = {
|
|
||||||
"chat_gpt_completion": False,
|
|
||||||
"model": self.default_model,
|
|
||||||
"prompt": "",
|
|
||||||
"auto_apply_ai_to_recording": False,
|
|
||||||
"current_tone": "None",
|
|
||||||
"hide_banner": False,
|
|
||||||
"input_device": "Default", # Add default for input device
|
|
||||||
"primary_device": "Select Device", # Also add for primary device
|
|
||||||
"secondary_device": "None", # Also add for secondary device
|
|
||||||
"hotkeys": {
|
|
||||||
"record_start_stop": ["ctrl", "shift", "0"],
|
|
||||||
"stop_recording": ["ctrl", "shift", "9"],
|
|
||||||
"play_last_audio": ["ctrl", "shift", "8"],
|
|
||||||
"cancel_operation": ["ctrl", "shift", "1"]
|
|
||||||
},
|
|
||||||
"max_tokens": 750
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Try to load existing settings
|
|
||||||
with open(settings_file, "r") as f:
|
|
||||||
settings = json.load(f)
|
|
||||||
|
|
||||||
# Check if settings need to be updated with new defaults
|
|
||||||
settings_updated = False
|
|
||||||
|
|
||||||
# Recursively update nested dictionaries with missing keys
|
|
||||||
def update_missing_settings(existing, defaults):
|
|
||||||
nonlocal settings_updated
|
|
||||||
for key, value in defaults.items():
|
|
||||||
if key not in existing:
|
|
||||||
existing[key] = value
|
|
||||||
settings_updated = True
|
|
||||||
elif isinstance(value, dict) and isinstance(existing[key], dict):
|
|
||||||
# Recursively update nested dictionaries
|
|
||||||
update_missing_settings(existing[key], value)
|
|
||||||
return existing
|
|
||||||
|
|
||||||
# Update settings with any missing values
|
|
||||||
settings = update_missing_settings(settings, default_settings)
|
|
||||||
|
|
||||||
# Save if any settings were updated
|
|
||||||
if settings_updated:
|
|
||||||
self.save_settings_to_JSON(settings)
|
|
||||||
print("Settings file updated with new default values")
|
|
||||||
|
|
||||||
except FileNotFoundError:
|
|
||||||
# Create new settings file with defaults if it doesn't exist
|
|
||||||
settings = default_settings
|
|
||||||
self.save_settings_to_JSON(settings)
|
|
||||||
|
|
||||||
return settings
|
|
||||||
|
|
||||||
def save_settings_to_JSON(self, settings):
|
def save_settings_to_JSON(self, settings):
|
||||||
settings_file = self.get_settings_file_path("settings.json")
|
"""Save complete settings using the SettingsManager."""
|
||||||
|
SettingsManager.save_settings(settings)
|
||||||
|
|
||||||
with open(settings_file, "w") as f:
|
def update_settings(self, partial_settings):
|
||||||
json.dump(settings, f)
|
"""Update specific settings without overwriting others."""
|
||||||
|
return SettingsManager.update_settings(partial_settings)
|
||||||
|
|
||||||
def get_settings_file_path(self, filename):
|
def get_settings_file_path(self, filename):
|
||||||
if platform.system() == 'Darwin': # Check if the OS is macOS
|
"""Get the settings file path using SettingsManager."""
|
||||||
mac_path = APIKeyManager.get_app_support_path_mac()
|
return SettingsManager.get_settings_file_path(filename)
|
||||||
return f"{mac_path}/{filename}"
|
|
||||||
else:
|
|
||||||
return filename # Default to current directory for non-macOS systems
|
|
||||||
|
|
||||||
# Methods for tone preset management
|
# Methods for tone preset management
|
||||||
def show_tone_presets_manager(self):
|
def show_tone_presets_manager(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user