Skip to content

Commit a8cb58e

Browse files
committed
change LibraryPrefs to allow identical values, add test
1 parent 9f1f460 commit a8cb58e

File tree

7 files changed

+75
-21
lines changed

7 files changed

+75
-21
lines changed

tagstudio/src/core/constants.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from enum import Enum
2-
31
VERSION: str = "9.3.2" # Major.Minor.Patch
42
VERSION_BRANCH: str = "" # Usually "" or "Pre-Release"
53

@@ -123,11 +121,3 @@
123121

124122
TAG_FAVORITE = 1
125123
TAG_ARCHIVED = 0
126-
127-
128-
class LibraryPrefs(Enum):
129-
IS_EXCLUDE_LIST: bool = True
130-
EXTENSION_LIST: list[str] = ["json", "xmp", "aae"]
131-
PAGE_SIZE: int = 500
132-
# increase in case of db breaking change (for now)
133-
DB_VERSION: int = 2

tagstudio/src/core/enums.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import enum
2+
from typing import Any
3+
from uuid import uuid4
24

35

46
class SettingItems(str, enum.Enum):
@@ -31,3 +33,31 @@ class MacroID(enum.Enum):
3133
BUILD_URL = "build_url"
3234
MATCH = "match"
3335
CLEAN_URL = "clean_url"
36+
37+
38+
class DefaultEnum(enum.Enum):
39+
"""Allow saving multiple identical values in property called .default."""
40+
41+
default: Any
42+
43+
def __new__(cls, value):
44+
# Create the enum instance
45+
obj = object.__new__(cls)
46+
# make value random
47+
obj._value_ = uuid4()
48+
# assign the actual value into .default property
49+
obj.default = value
50+
return obj
51+
52+
@property
53+
def value(self):
54+
raise AttributeError("access the value via .default property instead")
55+
56+
57+
class LibraryPrefs(DefaultEnum):
58+
"""Library preferences with default value accessible via .default property."""
59+
60+
IS_EXCLUDE_LIST = True
61+
EXTENSION_LIST: list[str] = [".json", ".xmp", ".aae"]
62+
PAGE_SIZE: int = 500
63+
DB_VERSION: int = 2

tagstudio/src/core/library/alchemy/library.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import re
22
import shutil
3+
import sys
34
import unicodedata
45
from dataclasses import dataclass
56
from datetime import UTC, datetime
@@ -34,8 +35,8 @@
3435
TAG_ARCHIVED,
3536
TAG_FAVORITE,
3637
TS_FOLDER_NAME,
37-
LibraryPrefs,
3838
)
39+
from ...enums import LibraryPrefs
3940
from .db import make_tables
4041
from .enums import FieldTypeEnum, FilterState, TagColor
4142
from .fields import (
@@ -164,9 +165,24 @@ def open_library(self, library_dir: Path, storage_path: str | None = None) -> Li
164165
# default tags may exist already
165166
session.rollback()
166167

168+
if "pytest" not in sys.modules:
169+
db_version = session.scalar(
170+
select(Preferences).where(Preferences.key == LibraryPrefs.DB_VERSION.name)
171+
)
172+
173+
if not db_version:
174+
# TODO - remove after #503 is merged and LibraryPrefs.DB_VERSION increased again
175+
return LibraryStatus(
176+
success=False,
177+
message=(
178+
"Library version mismatch.\n"
179+
f"Found: v0, expected: v{LibraryPrefs.DB_VERSION.default}"
180+
),
181+
)
182+
167183
for pref in LibraryPrefs:
168184
try:
169-
session.add(Preferences(key=pref.name, value=pref.value))
185+
session.add(Preferences(key=pref.name, value=pref.default))
170186
session.commit()
171187
except IntegrityError:
172188
logger.debug("preference already exists", pref=pref)
@@ -192,18 +208,18 @@ def open_library(self, library_dir: Path, storage_path: str | None = None) -> Li
192208
select(Preferences).where(Preferences.key == LibraryPrefs.DB_VERSION.name)
193209
)
194210
# if the db version is different, we cant proceed
195-
if db_version.value != LibraryPrefs.DB_VERSION.value:
211+
if db_version.value != LibraryPrefs.DB_VERSION.default:
196212
logger.error(
197213
"DB version mismatch",
198214
db_version=db_version.value,
199-
expected=LibraryPrefs.DB_VERSION.value,
215+
expected=LibraryPrefs.DB_VERSION.default,
200216
)
201217
# TODO - handle migration
202218
return LibraryStatus(
203219
success=False,
204220
message=(
205221
"Library version mismatch.\n"
206-
f"Found: v{db_version.value}, expected: v{LibraryPrefs.DB_VERSION.value}"
222+
f"Found: v{db_version.value}, expected: v{LibraryPrefs.DB_VERSION.default}"
207223
),
208224
)
209225

tagstudio/src/qt/modals/file_extension.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
QVBoxLayout,
1717
QWidget,
1818
)
19-
from src.core.constants import LibraryPrefs
19+
from src.core.enums import LibraryPrefs
2020
from src.core.library import Library
2121
from src.qt.widgets.panel import PanelWidget
2222

tagstudio/src/qt/ts_qt.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,9 @@
6161
TAG_FAVORITE,
6262
VERSION,
6363
VERSION_BRANCH,
64-
LibraryPrefs,
6564
)
6665
from src.core.driver import DriverMixin
67-
from src.core.enums import MacroID, SettingItems
66+
from src.core.enums import LibraryPrefs, MacroID, SettingItems
6867
from src.core.library.alchemy.enums import (
6968
FieldTypeEnum,
7069
FilterState,

tagstudio/tests/macros/test_refresh_dir.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
from tempfile import TemporaryDirectory
33

44
import pytest
5-
from src.core.constants import LibraryPrefs
5+
from src.core.enums import LibraryPrefs
6+
from src.core.library import Entry
67
from src.core.utils.refresh_dir import RefreshDirTracker
78

89
CWD = pathlib.Path(__file__).parent

tagstudio/tests/test_library.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from tempfile import TemporaryDirectory
33

44
import pytest
5-
from src.core.constants import LibraryPrefs
5+
from src.core.enums import DefaultEnum, LibraryPrefs
66
from src.core.library.alchemy import Entry
77
from src.core.library.alchemy.enums import FilterState
88
from src.core.library.alchemy.fields import TextField, _FieldID
@@ -197,7 +197,7 @@ def test_search_library_case_insensitive(library):
197197

198198
def test_preferences(library):
199199
for pref in LibraryPrefs:
200-
assert library.prefs(pref) == pref.value
200+
assert library.prefs(pref) == pref.default
201201

202202

203203
def test_save_windows_path(library, generate_tag):
@@ -383,3 +383,21 @@ def test_update_field_order(library, entry_full):
383383
assert entry.text_fields[0].value == "first"
384384
assert entry.text_fields[1].position == 1
385385
assert entry.text_fields[1].value == "second"
386+
387+
388+
def test_library_prefs_multiple_identical_vals():
389+
# check the preferences are inherited from DefaultEnum
390+
assert issubclass(LibraryPrefs, DefaultEnum)
391+
392+
# create custom settings with identical values
393+
class TestPrefs(DefaultEnum):
394+
FOO = 1
395+
BAR = 1
396+
397+
assert TestPrefs.FOO.default == 1
398+
assert TestPrefs.BAR.default == 1
399+
assert TestPrefs.BAR.name == "BAR"
400+
401+
# accessing .value should raise exception
402+
with pytest.raises(AttributeError):
403+
assert TestPrefs.BAR.value

0 commit comments

Comments
 (0)