276 lines
7.6 KiB
Python
276 lines
7.6 KiB
Python
from typing import Optional, Any, Union
|
|
from dataclasses import dataclass
|
|
from omegaconf import OmegaConf, DictConfig, ListConfig
|
|
import os
|
|
from pathlib import Path
|
|
|
|
|
|
@dataclass
|
|
class OpenAI:
|
|
api_key: str
|
|
model: str
|
|
|
|
def getattr(self, name: str):
|
|
return getattr(self, name)
|
|
|
|
def _setattr(self, name: str, value: Any):
|
|
setattr(self, name, value)
|
|
|
|
|
|
@dataclass
|
|
class Zotero:
|
|
api_key: str
|
|
library_id: str
|
|
library_type: str
|
|
|
|
def getattr(self, name: str):
|
|
return getattr(self, name)
|
|
|
|
def _setattr(self, name: str, value: Any):
|
|
setattr(self, name, value)
|
|
|
|
|
|
@dataclass
|
|
class Database:
|
|
name: str
|
|
path: Union[str, Path, None]
|
|
temp: Union[str, Path, None]
|
|
|
|
def getattr(self, name: str):
|
|
return getattr(self, name)
|
|
|
|
def _setattr(self, name: str, value: Any):
|
|
setattr(self, name, value)
|
|
|
|
def __post_init__(self):
|
|
if isinstance(self.path, str):
|
|
self.path = Path(self.path).expanduser()
|
|
if isinstance(self.temp, str):
|
|
self.temp = Path(self.temp).expanduser()
|
|
|
|
|
|
@dataclass
|
|
class Mail:
|
|
smtp_server: str
|
|
port: int
|
|
sender: str
|
|
sender_name: str
|
|
password: str
|
|
use_user_name: bool
|
|
printer_mail: str
|
|
user_name: str
|
|
signature: str | None = None
|
|
empty_signature = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
|
|
|
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style
|
|
type="text/css">
|
|
|
|
p, li { white-space: pre-wrap; }
|
|
|
|
hr { height: 1px; border-width: 0; }
|
|
|
|
li.unchecked::marker { content: "\2610"; }
|
|
|
|
li.checked::marker { content: "\2612"; }
|
|
|
|
</style></head><body style=" font-family:''Segoe UI''; font-size:9pt; font-weight:400;
|
|
font-style:normal;">
|
|
|
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px;
|
|
margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html>"""
|
|
|
|
def getattr(self, name: str):
|
|
return getattr(self, name)
|
|
|
|
def _setattr(self, name: str, value: Any):
|
|
setattr(self, name, value)
|
|
|
|
def setValue(self, **kwargs: Any):
|
|
for key, value in kwargs.items():
|
|
if hasattr(self, key):
|
|
setattr(self, key, value)
|
|
else:
|
|
raise KeyError(f"Invalid option: {key}")
|
|
|
|
|
|
class Icons:
|
|
def __init__(self):
|
|
self._path = None
|
|
self._colors = None
|
|
self._icons = None
|
|
|
|
def assign(self, key: str, value: Any):
|
|
setattr(self, key, value)
|
|
|
|
@property
|
|
def path(self):
|
|
return self._path
|
|
|
|
@path.setter
|
|
def path(self, value: Any):
|
|
self._path = value
|
|
|
|
@property
|
|
def colors(self):
|
|
return self._colors
|
|
|
|
@colors.setter
|
|
def colors(self, value: Any):
|
|
self._colors = value
|
|
|
|
@property
|
|
def icons(self):
|
|
return self._icons
|
|
|
|
@icons.setter
|
|
def icons(self, value: Any):
|
|
self._icons = value
|
|
|
|
def get(self, name: str):
|
|
return self.icons.get(name)
|
|
|
|
|
|
class Config:
|
|
"""A class to handle the configuration of the application. After initializing, it will try to load the config file and store it for future access. Any changes made can be saved to the file using the .save() method. Changes are used in real time in the app, if a restart is required, the Application will show a window.
|
|
|
|
Raises:
|
|
RuntimeError: Configuration not loaded
|
|
|
|
KeyError: Invalid option
|
|
|
|
"""
|
|
|
|
_config: Optional[Union[DictConfig, ListConfig]] = None
|
|
config_exists: bool = True
|
|
|
|
def __init__(self, config_path: str):
|
|
"""
|
|
Loads the configuration file and stores it for future access.
|
|
|
|
Args:
|
|
config_path (str): Path to the YAML configuration file.
|
|
|
|
Raises:
|
|
FileNotFoundError: Configuration file not found
|
|
"""
|
|
if not os.path.exists(config_path):
|
|
# copy base config file to the given path
|
|
base = "config/base_config.yaml"
|
|
if not os.path.exists(base):
|
|
raise FileNotFoundError(f"Base configuration file not found: {base}")
|
|
with open(base, "r") as base_file:
|
|
base_config = base_file.read()
|
|
with open(config_path, "w") as config_file:
|
|
config_file.write(base_config)
|
|
self.config_exists = False
|
|
self._config = OmegaConf.load(config_path)
|
|
self.config_path = config_path
|
|
|
|
@property
|
|
def exists(self) -> bool:
|
|
return self.config_exists
|
|
|
|
def save(self):
|
|
"""
|
|
Saves the current configuration to the file.
|
|
|
|
Args:
|
|
config_path (str): Path to the YAML configuration file.
|
|
"""
|
|
OmegaConf.save(self._config, self.config_path)
|
|
|
|
def reload(self):
|
|
"""
|
|
Reloads the configuration from the file.
|
|
"""
|
|
if self.config_path is not None:
|
|
self._config = OmegaConf.load(self.config_path)
|
|
|
|
@property
|
|
def zotero(self):
|
|
if self._config is None:
|
|
raise RuntimeError("Configuration not loaded")
|
|
return Zotero(**self._config.zotero)
|
|
|
|
def get_zotero_attr(self, name: str):
|
|
return getattr(self.zotero, name)
|
|
|
|
def set_zotero_attr(self, name: str, value: Any):
|
|
self.zotero._setattr(name, value)
|
|
|
|
@property
|
|
def database(self):
|
|
if self._config is None:
|
|
raise RuntimeError("Configuration not loaded")
|
|
return Database(**self._config.database)
|
|
|
|
@property
|
|
def database_attr(self, name: str):
|
|
return getattr(self.database, name)
|
|
|
|
@database_attr.setter
|
|
def database_attr(self, name: str, value: Any):
|
|
self.database._setattr(name, value)
|
|
|
|
@property
|
|
def openAI(self):
|
|
if self._config is None:
|
|
raise RuntimeError("Configuration not loaded")
|
|
return OpenAI(**self._config.openAI)
|
|
|
|
@property
|
|
def mail(self):
|
|
if self._config is None:
|
|
raise RuntimeError("Configuration not loaded")
|
|
return Mail(**self._config.mail)
|
|
|
|
def mail_attr(self, name: str):
|
|
return getattr(self.mail, name)
|
|
|
|
def set_mail_attr(self, name: str, value: Any):
|
|
if self._config is not None:
|
|
OmegaConf.update(self._config, f"mail.{name}", value)
|
|
|
|
def set_database_attr(self, name: str, value: Any):
|
|
if self._config is not None:
|
|
OmegaConf.update(self._config, f"database.{name}", value)
|
|
|
|
def set_zotero_attr(self, name: str, value: Any):
|
|
if self._config is not None:
|
|
OmegaConf.update(self._config, f"zotero.{name}", value)
|
|
|
|
def set_openai_attr(self, name: str, value: Any):
|
|
if self._config is not None:
|
|
OmegaConf.update(self._config, f"openAI.{name}", value)
|
|
|
|
def set_icon_attr(self, name: str, value: Any):
|
|
if self._config is not None:
|
|
OmegaConf.update(self._config, f"icons.{name}", value)
|
|
|
|
@property
|
|
def save_path(self):
|
|
if self._config is None:
|
|
raise RuntimeError("Configuration not loaded")
|
|
return self._config.save_path
|
|
|
|
@save_path.setter
|
|
def save_path(self, value: str):
|
|
if self._config is not None:
|
|
self._config.save_path = value
|
|
|
|
def load_config(self, path, filename):
|
|
return OmegaConf.load(os.path.join(path, filename))
|
|
|
|
@property
|
|
def icons(self):
|
|
if self._config is None:
|
|
raise RuntimeError("Configuration not loaded")
|
|
icons = Icons()
|
|
icons.assign("path", self._config.icon_path)
|
|
icons.assign("colors", self._config.colors)
|
|
icons.assign("icons", self._config.icons)
|
|
return icons
|
|
|
|
def dict(self):
|
|
return OmegaConf.to_container(self._config)
|