Skip to content

Commit

Permalink
sync stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
python357-1 committed Dec 24, 2024
1 parent 11d0553 commit dcf34fd
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 80 deletions.
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ structlog==24.4.0
typing_extensions>=3.10.0.0,<=4.11.0
ujson>=5.8.0,<=5.9.0
vtf2img==0.1.0
toml==0.10.2
toml==0.10.2
appdirs==1.4.4
13 changes: 7 additions & 6 deletions tagstudio/src/core/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
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 +23,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"]
5 changes: 5 additions & 0 deletions tagstudio/src/core/settings/libsettings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from pydantic import BaseModel, Field

class LibSettings(BaseModel):
# Cant think of any library-specific properties lol
test_prop: bool = False
19 changes: 16 additions & 3 deletions tagstudio/src/core/settings/tssettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import toml
from pydantic import BaseModel, Field

from typing import Optional

# NOTE: pydantic also has a BaseSettings class (from pydantic-settings) that allows any settings
# properties to be overwritten with environment variables. as tagstudio is not currently using
Expand All @@ -11,15 +11,27 @@ 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"))

print(settings_data)
settings_data["filename"] = str(path)
print(settings_data)

# if library: #TODO: add library-specific settings
# lib_settings_path = Path(library.folder / "settings.toml")
# lib_settings_data: dict[str, any]
Expand All @@ -28,7 +40,8 @@ def read_settings(path: Path | str, **kwargs) -> "TSSettings":
# lib_settings_data = tomllib.load(filedata)
# lib_settings = TSSettings(**lib_settings_data)

return TSSettings(**settings_data)
settings = TSSettings(**settings_data)
return settings

def to_dict(self) -> dict[str, any]:
d = dict[str, any]()
Expand Down
50 changes: 50 additions & 0 deletions tagstudio/src/core/tscacheddata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from pydantic import BaseModel, Field, ConfigDict
from src.core.library.alchemy.library import Library
from datetime import datetime
from appdirs import user_cache_dir
import structlog
from pathlib import Path
import toml
from typing import Optional

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:
print("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:
print("path is not none")
file = path

print(file)
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))
23 changes: 18 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,28 @@ 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.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
88 changes: 52 additions & 36 deletions tagstudio/src/qt/ts_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from itertools import zip_longest
from pathlib import Path
from queue import Queue
import datetime

# this import has side-effect of import PySide resources
import src.qt.resources_rc # noqa: F401
Expand Down Expand Up @@ -100,6 +101,7 @@
from src.qt.widgets.preview_panel import PreviewPanel
from src.qt.widgets.progress import ProgressWidget
from src.qt.widgets.thumb_renderer import ThumbRenderer
from src.core.tscacheddata import TSCachedData

# SIGQUIT is not defined on Windows
if sys.platform == "win32":
Expand Down Expand Up @@ -171,19 +173,18 @@ def __init__(self, backend, args):
if not path.exists():
logger.warning("Config File does not exist creating", path=path)
logger.info("Using Config File", path=path)
self.settings = QSettings(str(path), QSettings.Format.IniFormat)
self.settings = TSSettings.read_settings(path)
else:
self.settings = QSettings(
QSettings.Format.IniFormat,
QSettings.Scope.UserScope,
"TagStudio",
"TagStudio",
)
path = Path.home() / ".TagStudio" / "config.toml"
self.settings = TSSettings.read_settings(path)
logger.info(
"Config File not specified, using default one",
filename=self.settings.fileName(),
filename=self.settings.filename,
)


self.cache = TSCachedData.open()

def init_workers(self):
"""Init workers for rendering thumbnails."""
if not self.thumb_threads:
Expand Down Expand Up @@ -245,12 +246,6 @@ def start(self) -> None:
self.main_window.dragMoveEvent = self.drag_move_event # type: ignore[method-assign]
self.main_window.dropEvent = self.drop_event # type: ignore[method-assign]

self.settings_path = (
Path.home() / ".config/TagStudio" / "settings.toml"
) # TODO: put this somewhere else
self.newSettings = TSSettings.read_settings(
self.settings_path
) # TODO: make this cross-platform

splash_pixmap = QPixmap(":/images/splash.png")
splash_pixmap.setDevicePixelRatio(self.main_window.devicePixelRatio())
Expand Down Expand Up @@ -382,10 +377,10 @@ def start(self) -> None:
check_action = QAction("Open library on start", self)
check_action.setCheckable(True)
check_action.setChecked(
bool(self.settings.value(SettingItems.START_LOAD_LAST, defaultValue=True, type=bool))
self.settings.open_last_loaded_on_startup
)
check_action.triggered.connect(
lambda checked: self.settings.setValue(SettingItems.START_LOAD_LAST, checked)
lambda checked: setattr(self.settings, "open_last_loaded_on_startup", checked)
)
window_menu.addAction(check_action)

Expand Down Expand Up @@ -425,11 +420,11 @@ def create_dupe_files_modal():
show_libs_list_action = QAction("Show Recent Libraries", menu_bar)
show_libs_list_action.setCheckable(True)
show_libs_list_action.setChecked(
bool(self.settings.value(SettingItems.WINDOW_SHOW_LIBS, defaultValue=True, type=bool))
self.settings.show_library_list
)
show_libs_list_action.triggered.connect(
lambda checked: (
self.settings.setValue(SettingItems.WINDOW_SHOW_LIBS, checked),
setattr(self.settings, "show_library_list", checked),
self.toggle_libs_list(checked),
)
)
Expand Down Expand Up @@ -597,7 +592,7 @@ def close_library(self, is_shutdown: bool = False):
self.main_window.statusbar.showMessage("Closing Library...")
start_time = time.time()

self.settings.setValue(SettingItems.LAST_LIBRARY, str(self.lib.library_dir))
self.cache.last_library = self.lib.library_dir
self.settings.sync()

self.lib.close()
Expand Down Expand Up @@ -654,7 +649,7 @@ def add_tag_action_callback(self):

def open_settings_menu(self):
self.modal = PanelModal(
SettingsModal(self.newSettings),
SettingsModal(self.settings),
"Settings",
"Settings",
has_save=True,
Expand All @@ -664,8 +659,8 @@ def open_settings_menu(self):
self.modal.show()

def update_settings(self, settings: TSSettings):
self.newSettings = settings
self.newSettings.save(self.settings_path)
self.settings = settings
self.settings.save(self.settings.filename)

def select_all_action_callback(self):
self.selected = list(range(0, len(self.frame_content)))
Expand Down Expand Up @@ -1183,31 +1178,52 @@ def remove_recent_library(self, item_key: str):
self.settings.endGroup()
self.settings.sync()

self.cache.library_history.pop(datetime.datetime.strptime(item_key))


def update_libs_list(self, path: Path | str):
"""Add library to list in SettingItems.LIBS_LIST."""
"""Add library to list in tssettings"""
item_limit: int = 5
path = Path(path)

self.settings.beginGroup(SettingItems.LIBS_LIST)

all_libs = {str(time.time()): str(path)}

for item_key in self.settings.allKeys():
item_path = str(self.settings.value(item_key, type=str))
if Path(item_path) != path:
all_libs[item_key] = item_path
for access_time in self.cache.library_history:
lib = self.cache.library_history[access_time]
if Path(lib) != path:
all_libs[str(access_time)] = lib

# sort items, most recent first
all_libs_list = sorted(all_libs.items(), key=lambda item: item[0], reverse=True)
self.cache.library_history = {}
for key, value in all_libs_list[:item_limit]:
self.cache.library_history[key] = value

# remove previously saved items
self.settings.remove("")

for item_key, item_value in all_libs_list[:item_limit]:
self.settings.setValue(item_key, item_value)
#def update_libs_list(self, path: Path | str):
# """Add library to list in SettingItems.LIBS_LIST."""
# item_limit: int = 5
# path = Path(path)

self.settings.endGroup()
self.settings.sync()
# self.settings.beginGroup(SettingItems.LIBS_LIST)

# all_libs = {str(time.time()): str(path)}

# for item_key in self.settings.allKeys():
# item_path = str(self.settings.value(item_key, type=str))
# if Path(item_path) != path:
# all_libs[item_key] = item_path

# # sort items, most recent first
# all_libs_list = sorted(all_libs.items(), key=lambda item: item[0], reverse=True)

# # remove previously saved items
# self.settings.remove("")

# for item_key, item_value in all_libs_list[:item_limit]:
# self.settings.setValue(item_key, item_value)

# self.settings.endGroup()
# self.settings.sync()

def open_library(self, path: Path) -> None:
"""Open a TagStudio library."""
Expand Down
Loading

0 comments on commit dcf34fd

Please sign in to comment.