You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
11 KiB
213 lines
11 KiB
"""This module handles all operations involving the user's settings.""" |
|
|
|
import json |
|
from os import path |
|
from PyQt5.QtWidgets import QWidget |
|
from PyQt5.QtCore import QObject, pyqtSignal |
|
from ui import SettingsTab |
|
import ManageDB |
|
from Constants import * |
|
import GeneralUtils |
|
from GeneralUtils import JsonModel |
|
|
|
|
|
class Setting(Enum): |
|
"""An enum of all settings""" |
|
YEARLY_DIR = 0 |
|
OTHER_DIR = 1 |
|
REQUEST_INTERVAL = 2 |
|
REQUEST_TIMEOUT = 3 |
|
CONCURRENT_VENDORS = 4 |
|
CONCURRENT_REPORTS = 5 |
|
USER_AGENT = 6 |
|
|
|
|
|
class SettingsModel(JsonModel): |
|
"""This holds the user's settings. |
|
|
|
:param yearly_directory: The directory where yearly reports are saved. Yearly reports are reports that include all |
|
the available data for a year. |
|
:param other_directory: The default directory where non-yearly reports are saved. |
|
:param request_interval: The time to wait between each report request, per vendor. |
|
:param request_timeout: The time to wait before timing out a connection (seconds). |
|
:param concurrent_vendors: The max number of vendors to work on at a time. |
|
:param concurrent_reports: The max number of reports to work on at a time, per vendor. |
|
:param user_agent: The user-agent that's included in the header when making requests. |
|
""" |
|
def __init__(self, show_debug_messages: bool, yearly_directory: str, other_directory: str, request_interval: int, |
|
request_timeout: int, concurrent_vendors: int, concurrent_reports: int, user_agent: str, |
|
default_currency: str): |
|
self.show_debug_messages = show_debug_messages |
|
self.yearly_directory = path.abspath(yearly_directory) + path.sep |
|
self.other_directory = path.abspath(other_directory) + path.sep |
|
self.request_interval = request_interval |
|
self.request_timeout = request_timeout |
|
self.concurrent_vendors = concurrent_vendors |
|
self.concurrent_reports = concurrent_reports |
|
self.user_agent = user_agent |
|
self.default_currency = default_currency |
|
|
|
@classmethod |
|
def from_json(cls, json_dict: dict): |
|
show_debug_messages = json_dict["show_debug_messages"]\ |
|
if "show_debug_messages" in json_dict else SHOW_DEBUG_MESSAGES |
|
yearly_directory = json_dict["yearly_directory"]\ |
|
if "yearly_directory" in json_dict else YEARLY_DIR |
|
other_directory = json_dict["other_directory"]\ |
|
if "other_directory" in json_dict else OTHER_DIR |
|
request_interval = int(json_dict["request_interval"])\ |
|
if "request_interval" in json_dict else REQUEST_INTERVAL |
|
request_timeout = int(json_dict["request_timeout"])\ |
|
if "request_timeout" in json_dict else REQUEST_TIMEOUT |
|
concurrent_vendors = int(json_dict["concurrent_vendors"])\ |
|
if "concurrent_vendors" in json_dict else CONCURRENT_VENDORS |
|
concurrent_reports = int(json_dict["concurrent_reports"])\ |
|
if "concurrent_reports" in json_dict else CONCURRENT_REPORTS |
|
user_agent = json_dict["user_agent"]\ |
|
if "user_agent" in json_dict else USER_AGENT |
|
default_currency = json_dict["default_currency"]\ |
|
if "default_currency" in json_dict else DEFAULT_CURRENCY |
|
|
|
return cls(show_debug_messages, yearly_directory, other_directory, request_interval, request_timeout, |
|
concurrent_vendors, concurrent_reports, user_agent, default_currency) |
|
|
|
|
|
class SettingsController(QObject): |
|
"""Controls the Settings tab |
|
|
|
:param settings_widget: The settings widget. |
|
:param settings_ui: The UI for settings_widget. |
|
""" |
|
settings_changed_signal = pyqtSignal(SettingsModel) |
|
|
|
def __init__(self, settings_widget: QWidget, settings_ui: SettingsTab.Ui_settings_tab): |
|
# region General |
|
super().__init__() |
|
self.settings_widget = settings_widget |
|
|
|
json_string = GeneralUtils.read_json_file(SETTINGS_FILE_DIR + SETTINGS_FILE_NAME) |
|
json_dict = json.loads(json_string) |
|
self.settings = SettingsModel.from_json(json_dict) |
|
|
|
self.show_debug_checkbox = settings_ui.show_debug_check_box |
|
self.show_debug_checkbox.setChecked(self.settings.show_debug_messages) |
|
# endregion |
|
|
|
# region Reports |
|
self.yearly_dir_edit = settings_ui.yearly_directory_edit |
|
self.other_dir_edit = settings_ui.other_directory_edit |
|
self.request_interval_spin_box = settings_ui.request_interval_spin_box |
|
self.request_timeout_spin_box = settings_ui.request_timeout_spin_box |
|
self.concurrent_vendors_spin_box = settings_ui.concurrent_vendors_spin_box |
|
self.concurrent_reports_spin_box = settings_ui.concurrent_reports_spin_box |
|
self.user_agent_edit = settings_ui.user_agent_edit |
|
|
|
self.yearly_dir_edit.setText(self.settings.yearly_directory) |
|
self.other_dir_edit.setText(self.settings.other_directory) |
|
self.request_interval_spin_box.setValue(self.settings.request_interval) |
|
self.request_timeout_spin_box.setValue(self.settings.request_timeout) |
|
self.concurrent_vendors_spin_box.setValue(self.settings.concurrent_vendors) |
|
self.concurrent_reports_spin_box.setValue(self.settings.concurrent_reports) |
|
self.user_agent_edit.setText(self.settings.user_agent) |
|
|
|
settings_ui.yearly_directory_button.clicked.connect( |
|
lambda: self.on_directory_setting_clicked(Setting.YEARLY_DIR)) |
|
settings_ui.other_directory_button.clicked.connect( |
|
lambda: self.on_directory_setting_clicked(Setting.OTHER_DIR)) |
|
|
|
# Reports Help Messages |
|
settings_ui.yearly_directory_help_button.clicked.connect( |
|
lambda: GeneralUtils.show_message("This is where the calendar-year reports will be saved")) |
|
settings_ui.other_directory_help_button.clicked.connect( |
|
lambda: GeneralUtils.show_message("This is where the special and non-calendar-year date range reports will " |
|
"be saved by default")) |
|
settings_ui.request_interval_help_button.clicked.connect( |
|
lambda: GeneralUtils.show_message("The number of seconds the program will wait between sending each report " |
|
"request to a given vendor")) |
|
settings_ui.request_timeout_help_button.clicked.connect( |
|
lambda: GeneralUtils.show_message("The number of seconds the program will allow a vendor to respond to " |
|
"each report request before canceling it")) |
|
settings_ui.concurrent_vendors_help_button.clicked.connect( |
|
lambda: GeneralUtils.show_message("The maximum number of vendors to work on at the same time. " |
|
"If set too high, the UI might freeze while fetching reports but the " |
|
"fetch process will continue")) |
|
settings_ui.concurrent_reports_help_button.clicked.connect( |
|
lambda: GeneralUtils.show_message("The maximum number of reports to work on at the same time (per vendor). " |
|
"If set too high, the UI might freeze while fetching reports but the " |
|
"fetch process will continue")) |
|
settings_ui.user_agent_help_button.clicked.connect( |
|
lambda: GeneralUtils.show_message("How program identifies itself to the SUSHI servers. Some vendors will " |
|
"reject some particular user agents. Only change this if there is a " |
|
"known problem as it will affect all requests to all vendors. " |
|
"See Help for more information.")) |
|
settings_ui.default_currency_help_button.clicked.connect( |
|
lambda: GeneralUtils.show_message("The currency shown first in the Costs pulldown and also by Visual to " |
|
"label the local currency in the spreadsheets generated with the Cost " |
|
"Ratio option. Note: This doesn't have to be one of the pre-loaded " |
|
"currencies.")) |
|
|
|
# endregion |
|
|
|
# region Costs |
|
self.default_currency_combobox = settings_ui.settings_costs_default_currency_combobox |
|
self.default_currency_combobox.addItems(CURRENCY_LIST) |
|
self.default_currency_combobox.setCurrentText(self.settings.default_currency) |
|
# endregion |
|
|
|
# region Search |
|
# set up restore database button |
|
self.is_rebuilding_database = False |
|
self.update_database_dialog = ManageDB.UpdateDatabaseProgressDialogController(self.settings_widget) |
|
self.rebuild_database_button = settings_ui.settings_rebuild_database_button |
|
self.rebuild_database_button.clicked.connect(self.on_rebuild_database_clicked) |
|
# endregion |
|
|
|
settings_ui.save_button.clicked.connect(self.on_save_button_clicked) |
|
|
|
def on_directory_setting_clicked(self, setting: Setting): |
|
"""Handles the signal emitted when a choose folder button is clicked |
|
|
|
:param setting: The setting to be changed |
|
""" |
|
dir_path = GeneralUtils.choose_directory() |
|
if dir_path: |
|
if setting == Setting.YEARLY_DIR: |
|
self.yearly_dir_edit.setText(dir_path) |
|
elif setting == Setting.OTHER_DIR: |
|
self.other_dir_edit.setText(dir_path) |
|
|
|
def on_save_button_clicked(self): |
|
"""Handles the signal emitted when the save button is clicked""" |
|
self.update_settings() |
|
self.save_settings_to_disk() |
|
self.settings_changed_signal.emit(self.settings) |
|
GeneralUtils.show_message("Changes saved!") |
|
|
|
def on_rebuild_database_clicked(self): |
|
"""Restores the database when the restore database button is clicked""" |
|
if not self.is_rebuilding_database: # check if already running |
|
if GeneralUtils.ask_confirmation('Are you sure you want to rebuild the database?'): |
|
self.is_rebuilding_database = True |
|
self.update_database_dialog.update_database(ManageDB.get_all_report_files() + |
|
ManageDB.get_all_cost_files(), |
|
True) |
|
self.is_rebuilding_database = False |
|
else: |
|
if self.settings.show_debug_messages: print('Database is already being rebuilt') |
|
|
|
def update_settings(self): |
|
"""Updates the app's settings using the values entered on the UI""" |
|
self.settings.show_debug_messages = self.show_debug_checkbox.isChecked() |
|
self.settings.yearly_directory = self.yearly_dir_edit.text() |
|
self.settings.other_directory = self.other_dir_edit.text() |
|
self.settings.request_interval = self.request_interval_spin_box.value() |
|
self.settings.request_timeout = self.request_timeout_spin_box.value() |
|
self.settings.concurrent_vendors = self.concurrent_vendors_spin_box.value() |
|
self.settings.concurrent_reports = self.concurrent_reports_spin_box.value() |
|
self.settings.user_agent = self.user_agent_edit.text() |
|
self.settings.default_currency = self.default_currency_combobox.currentText() |
|
|
|
def save_settings_to_disk(self): |
|
"""Saves all settings to disk""" |
|
json_string = json.dumps(self.settings, default=lambda o: o.__dict__) |
|
GeneralUtils.save_json_file(SETTINGS_FILE_DIR, SETTINGS_FILE_NAME, json_string) |