Skip to content

Commit

Permalink
fix: merge conflicts and review suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
python357-1 committed Jan 14, 2025
1 parent 854c805 commit b74e872
Show file tree
Hide file tree
Showing 16 changed files with 133 additions and 206 deletions.
8 changes: 4 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
appdirs==1.4.4
chardet==5.2.0
ffmpeg-python==0.2.0
humanfriendly==10.0
Expand All @@ -7,16 +8,15 @@ opencv_python==4.10.0.84
pillow-heif==0.16.0
pillow-jxl-plugin==1.3.0
Pillow==10.3.0
pydantic==2.10.4
pydub==0.25.1
PySide6_Addons==6.8.0.1
PySide6_Essentials==6.8.0.1
PySide6==6.8.0.1
rawpy==0.22.0
SQLAlchemy==2.0.34
structlog==24.4.0
toml==0.10.2
typing_extensions
ujson>=5.8.0,<=5.9.0
vtf2img==0.1.0
toml==0.10.2
appdirs==1.4.4
pydantic==2.10.4
vtf2img==0.1.0
1 change: 1 addition & 0 deletions tagstudio/resources/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@
"preview.no_selection": "No Items Selected",
"select.all": "Select All",
"select.clear": "Clear Selection",
"settings.language": "Language",
"settings.open_library_on_start": "Open Library on Start",
"settings.show_filenames_in_grid": "Show Filenames in Grid",
"settings.show_recent_libraries": "Show Recent Libraries",
Expand Down
2 changes: 2 additions & 0 deletions tagstudio/src/core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@
TAG_META = 2
RESERVED_TAG_START = 0
RESERVED_TAG_END = 999

DEFAULT_LIB_VERSION = 3
9 changes: 0 additions & 9 deletions tagstudio/src/core/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,3 @@ def __new__(cls, value):
@property
def value(self):
raise AttributeError("access the value via .default property instead")


class LibraryPrefs(DefaultEnum):
"""Library preferences with default value accessible via .default property."""

IS_EXCLUDE_LIST = True
EXTENSION_LIST: list[str] = [".json", ".xmp", ".aae"]
PAGE_SIZE: int = 500
DB_VERSION: int = 3
98 changes: 47 additions & 51 deletions tagstudio/src/core/library/alchemy/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from os import makedirs
from pathlib import Path
from uuid import uuid4
from warnings import catch_warnings

import structlog
from humanfriendly import format_timespan
Expand All @@ -30,6 +29,7 @@
func,
or_,
select,
text,
update,
)
from sqlalchemy.exc import IntegrityError
Expand All @@ -44,6 +44,7 @@

from ...constants import (
BACKUP_FOLDER_NAME,
DEFAULT_LIB_VERSION,
LEGACY_TAG_FIELD_IDS,
RESERVED_TAG_END,
RESERVED_TAG_START,
Expand All @@ -52,7 +53,6 @@
TAG_META,
TS_FOLDER_NAME,
)
from ...enums import LibraryPrefs
from ...settings import LibSettings
from .db import make_tables
from .enums import MAX_SQL_VARIABLES, FieldTypeEnum, FilterState, SortingModeEnum, TagColor
Expand Down Expand Up @@ -257,13 +257,10 @@ def open_library(self, library_dir: Path, storage_path: str | None = None) -> Li
if storage_path == ":memory:":
self.storage_path = storage_path
is_new = True
self.settings = LibSettings(filename="")
return self.open_sqlite_library(library_dir, is_new)
else:
self.storage_path = library_dir / TS_FOLDER_NAME / self.SQL_FILENAME
settings_path = library_dir / TS_FOLDER_NAME / "libsettings.toml"

self.settings = LibSettings.open(settings_path)

if self.verify_ts_folder(library_dir) and (is_new := not self.storage_path.exists()):
json_path = library_dir / TS_FOLDER_NAME / self.JSON_FILENAME
if json_path.exists():
Expand Down Expand Up @@ -307,29 +304,6 @@ def open_sqlite_library(self, library_dir: Path, is_new: bool) -> LibraryStatus:
session.rollback()

# dont check db version when creating new library
if not is_new:
db_version = session.scalar(
select(Preferences).where(Preferences.key == LibraryPrefs.DB_VERSION.name)
)

if not db_version:
return LibraryStatus(
success=False,
message=(
"Library version mismatch.\n"
f"Found: v0, expected: v{LibraryPrefs.DB_VERSION.default}"
),
)

for pref in LibraryPrefs:
with catch_warnings(record=True):
try:
session.add(Preferences(key=pref.name, value=pref.default))
session.commit()
except IntegrityError:
logger.debug("preference already exists", pref=pref)
session.rollback()

for field in _FieldID:
try:
session.add(
Expand All @@ -346,21 +320,58 @@ def open_sqlite_library(self, library_dir: Path, is_new: bool) -> LibraryStatus:
logger.debug("ValueType already exists", field=field)
session.rollback()

db_version = session.scalar(
select(Preferences).where(Preferences.key == LibraryPrefs.DB_VERSION.name)
)
settings_path = library_dir / TS_FOLDER_NAME / "notafile.toml"

# Will be set already if library was opened in-memory
if self.settings is None:
if settings_path.exists():
self.settings = LibSettings.open(settings_path)
else:
if (
session.execute(
text(
"""
SELECT count(*)
FROM sqlite_master
WHERE type='table' AND lower(name)='preferences';
"""
)
).scalar()
== 0
):
# db was not created when settings were in db;
# use default settings, store at default location
self.settings = LibSettings(filename=str(settings_path))
else:
# copy settings from db, store them in default location on next save
prefs = session.scalars(select(Preferences))
settings = LibSettings(filename=str(settings_path))
for pref in prefs:
# the type ignores below are due to the fact that a Preference's value
# is defined as a dict, while none of them are actually dicts.
# i dont know why that is how it is, but it is
if pref.key == "IS_EXCLUDE_LIST":
settings.is_exclude_list = pref.value # type: ignore
elif pref.key == "EXTENSION_LIST":
settings.extension_list = pref.value # type: ignore
elif pref.key == "PAGE_SIZE":
settings.page_size = pref.value # type: ignore
elif pref.key == "DB_VERSION":
settings.db_version = pref.value # type: ignore

self.settings = settings
# if the db version is different, we cant proceed
if db_version.value != LibraryPrefs.DB_VERSION.default:
if not is_new and self.settings.db_version != DEFAULT_LIB_VERSION:
logger.error(
"DB version mismatch",
db_version=db_version.value,
expected=LibraryPrefs.DB_VERSION.default,
db_version=self.settings.db_version,
expected=DEFAULT_LIB_VERSION,
)
return LibraryStatus(
success=False,
message=(
"Library version mismatch.\n"
f"Found: v{db_version.value}, expected: v{LibraryPrefs.DB_VERSION.default}"
f"Found: v{self.settings.db_version}, expected: v{DEFAULT_LIB_VERSION}"
),
)

Expand Down Expand Up @@ -1107,21 +1118,6 @@ def update_parent_tags(self, tag, parent_ids, session):
)
session.add(parent_tag)

def prefs(self, key: LibraryPrefs):
# load given item from Preferences table
with Session(self.engine) as session:
return session.scalar(select(Preferences).where(Preferences.key == key.name)).value

def set_prefs(self, key: LibraryPrefs, value) -> None:
# set given item in Preferences table
with Session(self.engine) as session:
# load existing preference and update value
pref = session.scalar(select(Preferences).where(Preferences.key == key.name))
pref.value = value
session.add(pref)
session.commit()
# TODO - try/except

def mirror_entry_fields(self, *entries: Entry) -> None:
"""Mirror fields among multiple Entry items."""
fields = {}
Expand Down
8 changes: 6 additions & 2 deletions tagstudio/src/core/settings/libsettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
import toml
from pydantic import BaseModel, Field

from ..constants import DEFAULT_LIB_VERSION

logger = structlog.get_logger(__name__)


class LibSettings(BaseModel):
is_exclude_list: bool = Field(default=True)
extension_list: list[str] = Field(default=[".json", ".xmp", ".aae"])
page_size: int = Field(default=500)
db_version: int = Field(default=2)
db_version: int = Field(default=DEFAULT_LIB_VERSION)
filename: str = Field(default="")

@staticmethod
Expand All @@ -27,10 +29,12 @@ def open(path_value: Path | str) -> "LibSettings":
return LibSettings(**settings_data)

# either settings file did not exist or was empty - either way, use default settings
settings = LibSettings(**dict(filename=str(path)))
settings = LibSettings(filename=str(path))
return settings

def save(self):
if self.filename == "": # assume settings were opened for in-memory library
return
if not (parent_path := Path(self.filename).parent).exists():
parent_path.mkdir()

Expand Down
8 changes: 5 additions & 3 deletions tagstudio/src/core/settings/tssettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ def read_settings(path: Path | str) -> "TSSettings":
filecontents = file.read()
if len(filecontents.strip()) != 0:
settings_data = toml.loads(filecontents)
settings = TSSettings(**settings_data)
return settings
return TSSettings(**settings_data)

return TSSettings(**dict(filename=str(path)))
return TSSettings(filename=str(path))

def save(self, path: Path | str | None = None) -> None:
path_value: Path = Path(path) if isinstance(path, str) else Path(self.filename)
if path_value == "":
pass
# settings were probably opened for an in-memory library - save to preferences table

if not path_value.parent.exists():
path_value.parent.mkdir(parents=True, exist_ok=True)
Expand Down
5 changes: 2 additions & 3 deletions tagstudio/src/core/tscacheddata.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from datetime import datetime
from pathlib import Path

import structlog
Expand All @@ -16,7 +15,7 @@ class TSCachedData(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True)
last_library: str | None = Field(default=None)
# a dict of ISO formatted date strings -> paths
library_history: dict[str, str] = Field(default_factory=dict[datetime, str])
library_history: dict[str, str] = Field(default_factory=dict[str, str])

path: str = Field()

Expand Down Expand Up @@ -44,7 +43,7 @@ def open(path_value: Path | str | None = None) -> "TSCachedData":
logger.info("opening cache file at ", cache_location=path)
return TSCachedData(**cache_data)

return TSCachedData(**dict(path=str(default_cache_location)))
return TSCachedData(path=str(default_cache_location))

def save(self):
with open(self.path, "w") as f:
Expand Down
53 changes: 21 additions & 32 deletions tagstudio/src/qt/modals/settings_modal.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
QVBoxLayout,
)
from src.core.settings import TSSettings
from src.qt.translations import Translations
from src.qt.widgets.panel import PanelWidget


Expand All @@ -21,50 +22,38 @@ def __init__(self, settings: TSSettings):
self.main = QVBoxLayout(self)

# ---
self.language_Label = QLabel()
self.language_Value = QComboBox()
self.language_Row = QHBoxLayout()
self.language_Row.addWidget(self.language_Label)
self.language_Row.addWidget(self.language_Value)
language_row = QHBoxLayout(self)
language_label = QLabel(self)
Translations.translate_qobject(language_label, "settings.language")
language_value = QComboBox(self)
language_row.addWidget(language_label)
language_row.addWidget(language_value)

self.language_Label.setText("Language")
translations_folder = Path("tagstudio/resources/translations")
language_list = [x.stem for x in translations_folder.glob("*.json")]
self.language_Value.addItems(language_list)
self.language_Value.setCurrentIndex(language_list.index(self.tempSettings.language))
self.language_Value.currentTextChanged.connect(
language_value.addItems(language_list)
language_value.setCurrentIndex(language_list.index(self.tempSettings.language))
language_value.currentTextChanged.connect(
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 (requires restart):")
self.show_library_list_Value.setChecked(self.tempSettings.show_library_list)
show_filenames_row = QHBoxLayout(self)
show_filenames_label = QLabel(self)
Translations.translate_qobject(show_filenames_label, "settings.show_filenames_in_grid")
show_filenames_value = QCheckBox(self)

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

# ---
self.show_filenames_Label = QLabel()
self.show_filenames_Value = QCheckBox()
self.show_filenames_Row = QHBoxLayout()
self.show_filenames_Row.addWidget(self.show_filenames_Label)
self.show_filenames_Row.addWidget(self.show_filenames_Value)
self.show_filenames_Label.setText("Show filenames in grid (requires restart)")
self.show_filenames_Value.setChecked(self.tempSettings.show_filenames_in_grid)
show_filenames_value.setChecked(self.tempSettings.show_filenames_in_grid)
show_filenames_row.addWidget(show_filenames_label)
show_filenames_row.addWidget(show_filenames_value)

self.show_filenames_Value.stateChanged.connect(
show_filenames_value.stateChanged.connect(
lambda state: setattr(self.tempSettings, "show_filenames_in_grid", bool(state))
)
# ---
self.main.addLayout(self.language_Row)
self.main.addLayout(self.show_library_list_Row)
self.main.addLayout(self.show_filenames_Row)

self.main.addLayout(language_row)
self.main.addLayout(show_filenames_row)

def set_property(self, prop_name: str, value: Any) -> None:
setattr(self.tempSettings, prop_name, value)
Expand Down
Loading

0 comments on commit b74e872

Please sign in to comment.