Skip to content

Commit

Permalink
feat: settings menu MVP
Browse files Browse the repository at this point in the history
  • Loading branch information
python357-1 committed Dec 24, 2024
1 parent 11d0553 commit 037ebde
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 114 deletions.
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.12.8
6 changes: 4 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ PySide6==6.8.0.1
rawpy==0.22.0
SQLAlchemy==2.0.34
structlog==24.4.0
typing_extensions>=3.10.0.0,<=4.11.0
typing_extensions
ujson>=5.8.0,<=5.9.0
vtf2img==0.1.0
toml==0.10.2
toml==0.10.2
appdirs==1.4.4
pydantic==2.10.4
15 changes: 7 additions & 8 deletions tagstudio/src/core/driver.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
from pathlib import Path

import structlog
from PySide6.QtCore import QSettings
from src.core.constants import TS_FOLDER_NAME
from src.core.enums import SettingItems
from src.core.library.alchemy.library import LibraryStatus
from src.core.settings import TSSettings
from src.core.tscacheddata import TSCachedData

logger = structlog.get_logger(__name__)


class DriverMixin:
settings: QSettings
settings: TSSettings
cache: TSCachedData

def evaluate_path(self, open_path: str | None) -> LibraryStatus:
"""Check if the path of library is valid."""
Expand All @@ -20,17 +21,15 @@ def evaluate_path(self, open_path: str | None) -> LibraryStatus:
if not library_path.exists():
logger.error("Path does not exist.", open_path=open_path)
return LibraryStatus(success=False, message="Path does not exist.")
elif self.settings.value(
SettingItems.START_LOAD_LAST, defaultValue=True, type=bool
) and self.settings.value(SettingItems.LAST_LIBRARY):
library_path = Path(str(self.settings.value(SettingItems.LAST_LIBRARY)))
elif self.settings.open_last_loaded_on_startup and self.cache.last_lib:
library_path = Path(str(self.cache.last_library))
if not (library_path / TS_FOLDER_NAME).exists():
logger.error(
"TagStudio folder does not exist.",
library_path=library_path,
ts_folder=TS_FOLDER_NAME,
)
self.settings.setValue(SettingItems.LAST_LIBRARY, "")
self.cache.last_library = ""
# dont consider this a fatal error, just skip opening the library
library_path = None

Expand Down
4 changes: 3 additions & 1 deletion tagstudio/src/core/settings/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
__all__ = ["tssettings"]
from .tssettings import TSSettings

__all__ = ["TSSettings"]
6 changes: 6 additions & 0 deletions tagstudio/src/core/settings/libsettings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from pydantic import BaseModel


class LibSettings(BaseModel):
# Cant think of any library-specific properties lol
test_prop: bool = False
33 changes: 21 additions & 12 deletions tagstudio/src/core/settings/tssettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,25 @@ class TSSettings(BaseModel):
dark_mode: bool = Field(default=False)
language: str = Field(default="en-US")

# settings from the old SettingItem enum
open_last_loaded_on_startup: bool = Field(default=False)
show_library_list: bool = Field(default=True)
autoplay: bool = Field(default=False)

filename: str = Field()

@staticmethod
def read_settings(path: Path | str, **kwargs) -> "TSSettings":
# library = kwargs.get("library")
settings_data: dict[str, any] = dict()
if path.exists():
with open(path, "rb").read() as filecontents:
with open(path, "rb") as file:
filecontents = file.read()
if len(filecontents.strip()) != 0:
settings_data = toml.loads(filecontents.decode("utf-8"))

# if library: #TODO: add library-specific settings
# lib_settings_path = Path(library.folder / "settings.toml")
# lib_settings_data: dict[str, any]
# if lib_settings_path.exists:
# with open(lib_settings_path, "rb") as filedata:
# lib_settings_data = tomllib.load(filedata)
# lib_settings = TSSettings(**lib_settings_data)

return TSSettings(**settings_data)
settings_data["filename"] = str(path)
settings = TSSettings(**settings_data)
return settings

def to_dict(self) -> dict[str, any]:
d = dict[str, any]()
Expand All @@ -37,6 +38,14 @@ def to_dict(self) -> dict[str, any]:

return d

def save(self, path: Path | str) -> None:
def save(self, path: Path | str | None) -> None:
if isinstance(path, str):
path = Path(path)

if path is None:
path = self.filename
if not path.parent.exists():
path.parent.mkdir(parents=True, exist_ok=True)

with open(path, "w") as f:
toml.dump(self.to_dict(), f)
45 changes: 45 additions & 0 deletions tagstudio/src/core/tscacheddata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from datetime import datetime
from pathlib import Path

import structlog
import toml
from appdirs import user_cache_dir
from pydantic import BaseModel, ConfigDict, Field
from src.core.library.alchemy.library import Library

logger = structlog.get_logger(__name__)

cache_dir = Path(user_cache_dir()) / ".TagStudio"
cache_location = cache_dir / "cache.toml"


class TSCachedData(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True)
last_library: Library | None = Field(default=None)
library_history: dict[datetime, str] = Field(default_factory=dict[datetime, str])

path: str = Field()

@staticmethod
def open(path: str | None = None) -> "TSCachedData":
file: str | None = None

if path is None:
if not Path(cache_dir).exists():
logger.info("Cache directory does not exist - creating", path=cache_dir)
Path.mkdir(cache_dir)
if not Path(cache_location).exists():
logger.info("Cache file does not exist - creating", path=cache_location)
open(cache_location, "w").close()
file = str(cache_location)
else:
file = path

data = toml.load(file)
data["path"] = str(path) if path is not None else str(cache_location)
cached_data = TSCachedData(**data)
return cached_data

def save(self):
with open(self.path, "wb") as f:
f.writelines(toml.dumps(self))
24 changes: 19 additions & 5 deletions tagstudio/src/qt/modals/settings_modal.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
QLabel,
QVBoxLayout,
)
from src.core.settings import TSSettings
from src.core.settings import tssettings
from src.qt.widgets.panel import PanelWidget


class SettingsModal(PanelWidget):
def __init__(self, settings: TSSettings):
def __init__(self, settings: tssettings):
super().__init__()
self.tempSettings = copy.deepcopy(settings)

Expand All @@ -29,7 +29,7 @@ def __init__(self, settings: TSSettings):
self.darkMode_Value.setChecked(self.tempSettings.dark_mode)

self.darkMode_Value.stateChanged.connect(
lambda state: self.set_property("dark_mode", bool(state))
lambda state: setattr(self.tempSettings, "dark_mode", bool(state))
)

# ---
Expand All @@ -49,15 +49,29 @@ def __init__(self, settings: TSSettings):
self.language_Value.addItems(language_list)
self.language_Value.setCurrentIndex(language_list.index(self.tempSettings.language))
self.language_Value.currentTextChanged.connect(
lambda text: self.set_property("language", text)
lambda text: setattr(self.tempSettings, "language", text)
)

# ---
self.show_library_list_Label = QLabel()
self.show_library_list_Value = QCheckBox()
self.show_library_list_Row = QHBoxLayout()
self.show_library_list_Row.addWidget(self.show_library_list_Label)
self.show_library_list_Row.addWidget(self.show_library_list_Value)
self.show_library_list_Label.setText("Load library list on startup:")
self.show_library_list_Value.setChecked(self.tempSettings.show_library_list)

self.show_library_list_Value.stateChanged.connect(
lambda state: setattr(self.tempSettings, "show_library_list", bool(state))
)

# ---
self.main.addLayout(self.darkMode_Row)
self.main.addLayout(self.language_Row)
self.main.addLayout(self.show_library_list_Row)

def set_property(self, prop_name: str, value: any) -> None:
setattr(self.tempSettings, prop_name, value)

def get_content(self) -> TSSettings:
def get_content(self) -> tssettings:
return self.tempSettings
Loading

0 comments on commit 037ebde

Please sign in to comment.