Skip to content

Commit dcf34fd

Browse files
committed
sync stuff
1 parent 11d0553 commit dcf34fd

File tree

11 files changed

+204
-80
lines changed

11 files changed

+204
-80
lines changed

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ structlog==24.4.0
1717
typing_extensions>=3.10.0.0,<=4.11.0
1818
ujson>=5.8.0,<=5.9.0
1919
vtf2img==0.1.0
20-
toml==0.10.2
20+
toml==0.10.2
21+
appdirs==1.4.4

tagstudio/src/core/driver.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
from src.core.constants import TS_FOLDER_NAME
66
from src.core.enums import SettingItems
77
from src.core.library.alchemy.library import LibraryStatus
8+
from src.core.settings import TSSettings
9+
from src.core.tscacheddata import TSCachedData
810

911
logger = structlog.get_logger(__name__)
1012

1113

1214
class DriverMixin:
13-
settings: QSettings
15+
settings: TSSettings
16+
cache: TSCachedData
1417

1518
def evaluate_path(self, open_path: str | None) -> LibraryStatus:
1619
"""Check if the path of library is valid."""
@@ -20,17 +23,15 @@ def evaluate_path(self, open_path: str | None) -> LibraryStatus:
2023
if not library_path.exists():
2124
logger.error("Path does not exist.", open_path=open_path)
2225
return LibraryStatus(success=False, message="Path does not exist.")
23-
elif self.settings.value(
24-
SettingItems.START_LOAD_LAST, defaultValue=True, type=bool
25-
) and self.settings.value(SettingItems.LAST_LIBRARY):
26-
library_path = Path(str(self.settings.value(SettingItems.LAST_LIBRARY)))
26+
elif self.settings.open_last_loaded_on_startup and self.cache.last_lib:
27+
library_path = Path(str(self.cache.last_library))
2728
if not (library_path / TS_FOLDER_NAME).exists():
2829
logger.error(
2930
"TagStudio folder does not exist.",
3031
library_path=library_path,
3132
ts_folder=TS_FOLDER_NAME,
3233
)
33-
self.settings.setValue(SettingItems.LAST_LIBRARY, "")
34+
self.cache.last_library = ""
3435
# dont consider this a fatal error, just skip opening the library
3536
library_path = None
3637

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
__all__ = ["tssettings"]
1+
from .tssettings import TSSettings
2+
3+
__all__ = ["TSSettings"]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from pydantic import BaseModel, Field
2+
3+
class LibSettings(BaseModel):
4+
# Cant think of any library-specific properties lol
5+
test_prop: bool = False

tagstudio/src/core/settings/tssettings.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import toml
44
from pydantic import BaseModel, Field
5-
5+
from typing import Optional
66

77
# NOTE: pydantic also has a BaseSettings class (from pydantic-settings) that allows any settings
88
# properties to be overwritten with environment variables. as tagstudio is not currently using
@@ -11,15 +11,27 @@ class TSSettings(BaseModel):
1111
dark_mode: bool = Field(default=False)
1212
language: str = Field(default="en-US")
1313

14+
#settings from the old SettingItem enum
15+
open_last_loaded_on_startup: bool = Field(default=False)
16+
show_library_list: bool = Field(default=True)
17+
autoplay: bool = Field(default=False)
18+
19+
filename: str = Field()
20+
1421
@staticmethod
1522
def read_settings(path: Path | str, **kwargs) -> "TSSettings":
1623
# library = kwargs.get("library")
1724
settings_data: dict[str, any] = dict()
1825
if path.exists():
19-
with open(path, "rb").read() as filecontents:
26+
with open(path, "rb") as file:
27+
filecontents = file.read()
2028
if len(filecontents.strip()) != 0:
2129
settings_data = toml.loads(filecontents.decode("utf-8"))
2230

31+
print(settings_data)
32+
settings_data["filename"] = str(path)
33+
print(settings_data)
34+
2335
# if library: #TODO: add library-specific settings
2436
# lib_settings_path = Path(library.folder / "settings.toml")
2537
# lib_settings_data: dict[str, any]
@@ -28,7 +40,8 @@ def read_settings(path: Path | str, **kwargs) -> "TSSettings":
2840
# lib_settings_data = tomllib.load(filedata)
2941
# lib_settings = TSSettings(**lib_settings_data)
3042

31-
return TSSettings(**settings_data)
43+
settings = TSSettings(**settings_data)
44+
return settings
3245

3346
def to_dict(self) -> dict[str, any]:
3447
d = dict[str, any]()

tagstudio/src/core/tscacheddata.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from pydantic import BaseModel, Field, ConfigDict
2+
from src.core.library.alchemy.library import Library
3+
from datetime import datetime
4+
from appdirs import user_cache_dir
5+
import structlog
6+
from pathlib import Path
7+
import toml
8+
from typing import Optional
9+
10+
logger = structlog.get_logger(__name__)
11+
12+
cache_dir = Path(user_cache_dir()) / ".TagStudio"
13+
cache_location = cache_dir / "cache.toml"
14+
15+
class TSCachedData(BaseModel):
16+
model_config=ConfigDict(arbitrary_types_allowed=True)
17+
last_library: Library | None = Field(default=None)
18+
library_history: dict[datetime, str] = Field(default_factory=dict[datetime, str])
19+
20+
path: str = Field()
21+
22+
@staticmethod
23+
def open(path: str | None = None) -> "TSCachedData":
24+
file: str | None = None
25+
26+
if path is None:
27+
print("path is none")
28+
if not Path(cache_dir).exists():
29+
logger.info(
30+
"Cache directory does not exist - creating",
31+
path=cache_dir
32+
)
33+
Path.mkdir(cache_dir)
34+
if not Path(cache_location).exists():
35+
logger.info("Cache file does not exist - creating", path=cache_location)
36+
open(cache_location, "w").close()
37+
file = str(cache_location)
38+
else:
39+
print("path is not none")
40+
file = path
41+
42+
print(file)
43+
data = toml.load(file)
44+
data["path"] = str(path) if path is not None else str(cache_location)
45+
cached_data = TSCachedData(**data)
46+
return cached_data
47+
48+
def save(self):
49+
with open(self.path, "wb") as f:
50+
f.writelines(toml.dumps(self))

tagstudio/src/qt/modals/settings_modal.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
QLabel,
88
QVBoxLayout,
99
)
10-
from src.core.settings import TSSettings
10+
from src.core.settings import tssettings
1111
from src.qt.widgets.panel import PanelWidget
1212

1313

1414
class SettingsModal(PanelWidget):
15-
def __init__(self, settings: TSSettings):
15+
def __init__(self, settings: tssettings):
1616
super().__init__()
1717
self.tempSettings = copy.deepcopy(settings)
1818

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

3131
self.darkMode_Value.stateChanged.connect(
32-
lambda state: self.set_property("dark_mode", bool(state))
32+
lambda state: setattr(self.tempSettings, "dark_mode", bool(state))
3333
)
3434

3535
# ---
@@ -49,15 +49,28 @@ def __init__(self, settings: TSSettings):
4949
self.language_Value.addItems(language_list)
5050
self.language_Value.setCurrentIndex(language_list.index(self.tempSettings.language))
5151
self.language_Value.currentTextChanged.connect(
52-
lambda text: self.set_property("language", text)
52+
lambda text: setattr(self.tempSettings, "language", text)
53+
)
54+
55+
# ---
56+
self.show_library_list_Label = QLabel()
57+
self.show_library_list_Value = QCheckBox()
58+
self.show_library_list_Row = QHBoxLayout()
59+
self.show_library_list_Row.addWidget(self.show_library_list_Label)
60+
self.show_library_list_Row.addWidget(self.show_library_list_Value)
61+
self.show_library_list_Label.setText("Load library list on startup:")
62+
63+
self.show_library_list_Value.stateChanged.connect(
64+
lambda state: setattr(self.tempSettings, "show_library_list", bool(state))
5365
)
5466

5567
# ---
5668
self.main.addLayout(self.darkMode_Row)
5769
self.main.addLayout(self.language_Row)
70+
self.main.addLayout(self.show_library_list_Row)
5871

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

62-
def get_content(self) -> TSSettings:
75+
def get_content(self) -> tssettings:
6376
return self.tempSettings

tagstudio/src/qt/ts_qt.py

Lines changed: 52 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from itertools import zip_longest
2020
from pathlib import Path
2121
from queue import Queue
22+
import datetime
2223

2324
# this import has side-effect of import PySide resources
2425
import src.qt.resources_rc # noqa: F401
@@ -100,6 +101,7 @@
100101
from src.qt.widgets.preview_panel import PreviewPanel
101102
from src.qt.widgets.progress import ProgressWidget
102103
from src.qt.widgets.thumb_renderer import ThumbRenderer
104+
from src.core.tscacheddata import TSCachedData
103105

104106
# SIGQUIT is not defined on Windows
105107
if sys.platform == "win32":
@@ -171,19 +173,18 @@ def __init__(self, backend, args):
171173
if not path.exists():
172174
logger.warning("Config File does not exist creating", path=path)
173175
logger.info("Using Config File", path=path)
174-
self.settings = QSettings(str(path), QSettings.Format.IniFormat)
176+
self.settings = TSSettings.read_settings(path)
175177
else:
176-
self.settings = QSettings(
177-
QSettings.Format.IniFormat,
178-
QSettings.Scope.UserScope,
179-
"TagStudio",
180-
"TagStudio",
181-
)
178+
path = Path.home() / ".TagStudio" / "config.toml"
179+
self.settings = TSSettings.read_settings(path)
182180
logger.info(
183181
"Config File not specified, using default one",
184-
filename=self.settings.fileName(),
182+
filename=self.settings.filename,
185183
)
186184

185+
186+
self.cache = TSCachedData.open()
187+
187188
def init_workers(self):
188189
"""Init workers for rendering thumbnails."""
189190
if not self.thumb_threads:
@@ -245,12 +246,6 @@ def start(self) -> None:
245246
self.main_window.dragMoveEvent = self.drag_move_event # type: ignore[method-assign]
246247
self.main_window.dropEvent = self.drop_event # type: ignore[method-assign]
247248

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

255250
splash_pixmap = QPixmap(":/images/splash.png")
256251
splash_pixmap.setDevicePixelRatio(self.main_window.devicePixelRatio())
@@ -382,10 +377,10 @@ def start(self) -> None:
382377
check_action = QAction("Open library on start", self)
383378
check_action.setCheckable(True)
384379
check_action.setChecked(
385-
bool(self.settings.value(SettingItems.START_LOAD_LAST, defaultValue=True, type=bool))
380+
self.settings.open_last_loaded_on_startup
386381
)
387382
check_action.triggered.connect(
388-
lambda checked: self.settings.setValue(SettingItems.START_LOAD_LAST, checked)
383+
lambda checked: setattr(self.settings, "open_last_loaded_on_startup", checked)
389384
)
390385
window_menu.addAction(check_action)
391386

@@ -425,11 +420,11 @@ def create_dupe_files_modal():
425420
show_libs_list_action = QAction("Show Recent Libraries", menu_bar)
426421
show_libs_list_action.setCheckable(True)
427422
show_libs_list_action.setChecked(
428-
bool(self.settings.value(SettingItems.WINDOW_SHOW_LIBS, defaultValue=True, type=bool))
423+
self.settings.show_library_list
429424
)
430425
show_libs_list_action.triggered.connect(
431426
lambda checked: (
432-
self.settings.setValue(SettingItems.WINDOW_SHOW_LIBS, checked),
427+
setattr(self.settings, "show_library_list", checked),
433428
self.toggle_libs_list(checked),
434429
)
435430
)
@@ -597,7 +592,7 @@ def close_library(self, is_shutdown: bool = False):
597592
self.main_window.statusbar.showMessage("Closing Library...")
598593
start_time = time.time()
599594

600-
self.settings.setValue(SettingItems.LAST_LIBRARY, str(self.lib.library_dir))
595+
self.cache.last_library = self.lib.library_dir
601596
self.settings.sync()
602597

603598
self.lib.close()
@@ -654,7 +649,7 @@ def add_tag_action_callback(self):
654649

655650
def open_settings_menu(self):
656651
self.modal = PanelModal(
657-
SettingsModal(self.newSettings),
652+
SettingsModal(self.settings),
658653
"Settings",
659654
"Settings",
660655
has_save=True,
@@ -664,8 +659,8 @@ def open_settings_menu(self):
664659
self.modal.show()
665660

666661
def update_settings(self, settings: TSSettings):
667-
self.newSettings = settings
668-
self.newSettings.save(self.settings_path)
662+
self.settings = settings
663+
self.settings.save(self.settings.filename)
669664

670665
def select_all_action_callback(self):
671666
self.selected = list(range(0, len(self.frame_content)))
@@ -1183,31 +1178,52 @@ def remove_recent_library(self, item_key: str):
11831178
self.settings.endGroup()
11841179
self.settings.sync()
11851180

1181+
self.cache.library_history.pop(datetime.datetime.strptime(item_key))
1182+
1183+
11861184
def update_libs_list(self, path: Path | str):
1187-
"""Add library to list in SettingItems.LIBS_LIST."""
1185+
"""Add library to list in tssettings"""
11881186
item_limit: int = 5
11891187
path = Path(path)
11901188

1191-
self.settings.beginGroup(SettingItems.LIBS_LIST)
1192-
11931189
all_libs = {str(time.time()): str(path)}
11941190

1195-
for item_key in self.settings.allKeys():
1196-
item_path = str(self.settings.value(item_key, type=str))
1197-
if Path(item_path) != path:
1198-
all_libs[item_key] = item_path
1191+
for access_time in self.cache.library_history:
1192+
lib = self.cache.library_history[access_time]
1193+
if Path(lib) != path:
1194+
all_libs[str(access_time)] = lib
11991195

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

1203-
# remove previously saved items
1204-
self.settings.remove("")
12051201

1206-
for item_key, item_value in all_libs_list[:item_limit]:
1207-
self.settings.setValue(item_key, item_value)
1202+
#def update_libs_list(self, path: Path | str):
1203+
# """Add library to list in SettingItems.LIBS_LIST."""
1204+
# item_limit: int = 5
1205+
# path = Path(path)
12081206

1209-
self.settings.endGroup()
1210-
self.settings.sync()
1207+
# self.settings.beginGroup(SettingItems.LIBS_LIST)
1208+
1209+
# all_libs = {str(time.time()): str(path)}
1210+
1211+
# for item_key in self.settings.allKeys():
1212+
# item_path = str(self.settings.value(item_key, type=str))
1213+
# if Path(item_path) != path:
1214+
# all_libs[item_key] = item_path
1215+
1216+
# # sort items, most recent first
1217+
# all_libs_list = sorted(all_libs.items(), key=lambda item: item[0], reverse=True)
1218+
1219+
# # remove previously saved items
1220+
# self.settings.remove("")
1221+
1222+
# for item_key, item_value in all_libs_list[:item_limit]:
1223+
# self.settings.setValue(item_key, item_value)
1224+
1225+
# self.settings.endGroup()
1226+
# self.settings.sync()
12111227

12121228
def open_library(self, path: Path) -> None:
12131229
"""Open a TagStudio library."""

0 commit comments

Comments
 (0)