mirror of
https://github.com/TagStudioDev/TagStudio.git
synced 2026-05-09 13:53:51 +00:00
fix: remove preferences table (#1298)
* refactor: cleanup parameters of open_library and open_sqlite_library * doc: notes on what tables are affected by which migration steps * refactor(migration order): move DBv6 repairs * refactor(migration order): move DBv8 repairs * refactor(migration order): move DBv9 repairs * refactor(migration order): move DBv100 repairs * refactor(migration order): move DBv102 repairs * refactor: merge migration methods * doc: final comment changes * fix: query tag ids independent of future DB changes * feat: remove preferences table * refactor: various references to LibraryPrefs * fix: update josn migration UI * refactor: remove last vestiges of preferences table * fix: remove newly unnecessary translations * doc: document library format changes * refactor: merge the two methods used for migration 104 * fix: typo in sql statement * fix: add back support for preferences table in get_version * fix: properly remove directory in test * fix: incorrect schema check in get_version * fix: update search lib via migration * fix: update assert in test * fix: ignore element order in assert in test * fix: use correct path * fix: better test output --------- Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
This commit is contained in:
@@ -128,7 +128,15 @@ Migration from the legacy JSON format is provided via a walkthrough when opening
|
||||
|
||||
| Used From | Format | Location |
|
||||
| ----------------------------------------------------------------------- | ------ | ----------------------------------------------- |
|
||||
| [#1139](https://github.com/TagStudioDev/TagStudio/pull/1139) | SQLite | `<Library Folder>`/.TagStudio/ts_library.sqlite |
|
||||
| [#1139](https://github.com/TagStudioDev/TagStudio/pull/1139) | SQLite | `<Library Folder>`/.TagStudio/ts_library.sqlite |
|
||||
|
||||
- Adds the `is_hidden` column to the `tags` table (default `0`). Used for excluding entries tagged with hidden tags from library searches.
|
||||
- Sets the `is_hidden` field on the built-in Archived tag to `1`, to match the Archived tag now being hidden by default.
|
||||
- Sets the `is_hidden` field on the built-in Archived tag to `1`, to match the Archived tag now being hidden by default.
|
||||
|
||||
#### Version 104
|
||||
|
||||
| Used From | Format | Location |
|
||||
| ----------------------------------------------------------------------- | ------ | ----------------------------------------------- |
|
||||
| [#1298](https://github.com/TagStudioDev/TagStudio/pull/1298) | SQLite | `<Library Folder>`/.TagStudio/ts_library.sqlite |
|
||||
|
||||
- Removes the `preferences` table, after migrating the contained extension list to the .ts_ignore file, if necessary.
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
# Created for TagStudio: https://github.com/CyanVoxel/TagStudio
|
||||
|
||||
import enum
|
||||
from typing import Any
|
||||
from uuid import uuid4
|
||||
|
||||
|
||||
class SettingItems(str, enum.Enum):
|
||||
@@ -57,30 +55,3 @@ class MacroID(enum.Enum):
|
||||
BUILD_URL = "build_url"
|
||||
MATCH = "match"
|
||||
CLEAN_URL = "clean_url"
|
||||
|
||||
|
||||
class DefaultEnum(enum.Enum):
|
||||
"""Allow saving multiple identical values in property called .default."""
|
||||
|
||||
default: Any
|
||||
|
||||
def __new__(cls, value):
|
||||
# Create the enum instance
|
||||
obj = object.__new__(cls)
|
||||
# make value random
|
||||
obj._value_ = uuid4()
|
||||
# assign the actual value into .default property
|
||||
obj.default = value
|
||||
return obj
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
raise AttributeError("access the value via .default property instead")
|
||||
|
||||
|
||||
# TODO: Remove DefaultEnum and LibraryPrefs classes once remaining values are removed.
|
||||
class LibraryPrefs(DefaultEnum):
|
||||
"""Library preferences with default value accessible via .default property."""
|
||||
|
||||
IS_EXCLUDE_LIST = True
|
||||
EXTENSION_LIST = [".json", ".xmp", ".aae"]
|
||||
|
||||
@@ -8,10 +8,9 @@ from sqlalchemy import text
|
||||
SQL_FILENAME: str = "ts_library.sqlite"
|
||||
JSON_FILENAME: str = "ts_library.json"
|
||||
|
||||
DB_VERSION_LEGACY_KEY: str = "DB_VERSION"
|
||||
DB_VERSION_CURRENT_KEY: str = "CURRENT"
|
||||
DB_VERSION_INITIAL_KEY: str = "INITIAL"
|
||||
DB_VERSION: int = 103
|
||||
DB_VERSION: int = 104
|
||||
|
||||
TAG_CHILDREN_QUERY = text("""
|
||||
WITH RECURSIVE ChildTags AS (
|
||||
|
||||
@@ -16,7 +16,7 @@ from dataclasses import dataclass
|
||||
from datetime import UTC, datetime
|
||||
from os import makedirs
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING
|
||||
from uuid import uuid4
|
||||
from warnings import catch_warnings
|
||||
|
||||
@@ -53,7 +53,6 @@ from sqlalchemy.orm import (
|
||||
noload,
|
||||
selectinload,
|
||||
)
|
||||
from typing_extensions import deprecated
|
||||
|
||||
from tagstudio.core.constants import (
|
||||
BACKUP_FOLDER_NAME,
|
||||
@@ -67,13 +66,11 @@ from tagstudio.core.constants import (
|
||||
TAG_META,
|
||||
TS_FOLDER_NAME,
|
||||
)
|
||||
from tagstudio.core.enums import LibraryPrefs
|
||||
from tagstudio.core.library.alchemy import default_color_groups
|
||||
from tagstudio.core.library.alchemy.constants import (
|
||||
DB_VERSION,
|
||||
DB_VERSION_CURRENT_KEY,
|
||||
DB_VERSION_INITIAL_KEY,
|
||||
DB_VERSION_LEGACY_KEY,
|
||||
JSON_FILENAME,
|
||||
SQL_FILENAME,
|
||||
TAG_CHILDREN_QUERY,
|
||||
@@ -96,7 +93,6 @@ from tagstudio.core.library.alchemy.models import (
|
||||
Entry,
|
||||
Folder,
|
||||
Namespace,
|
||||
Preferences,
|
||||
Tag,
|
||||
TagAlias,
|
||||
TagColorGroup,
|
||||
@@ -104,6 +100,7 @@ from tagstudio.core.library.alchemy.models import (
|
||||
Version,
|
||||
)
|
||||
from tagstudio.core.library.alchemy.visitors import SQLBoolExpressionBuilder
|
||||
from tagstudio.core.library.ignore import migrate_ext_list
|
||||
from tagstudio.core.library.json.library import Library as JsonLibrary
|
||||
from tagstudio.core.utils.types import unwrap
|
||||
from tagstudio.qt.translations import Translations
|
||||
@@ -318,9 +315,10 @@ class Library:
|
||||
value=v,
|
||||
)
|
||||
|
||||
# Preferences
|
||||
self.set_prefs(LibraryPrefs.EXTENSION_LIST, [x.strip(".") for x in json_lib.ext_list])
|
||||
self.set_prefs(LibraryPrefs.IS_EXCLUDE_LIST, json_lib.is_exclude_list)
|
||||
# extension include/exclude list
|
||||
(unwrap(self.library_dir) / TS_FOLDER_NAME / IGNORE_NAME).write_text(
|
||||
migrate_ext_list([x.strip(".") for x in json_lib.ext_list], json_lib.is_exclude_list)
|
||||
)
|
||||
|
||||
end_time = time.time()
|
||||
logger.info(f"Library Converted! ({format_timespan(end_time - start_time)})")
|
||||
@@ -458,15 +456,6 @@ class Library:
|
||||
|
||||
# Ensure version rows are present
|
||||
with catch_warnings(record=True):
|
||||
# NOTE: The "Preferences" table is depreciated and will be removed in the future.
|
||||
# The DB_VERSION is still being set to it in order to remain backwards-compatible
|
||||
# with existing TagStudio versions until it is removed.
|
||||
try:
|
||||
session.add(Preferences(key=DB_VERSION_LEGACY_KEY, value=DB_VERSION))
|
||||
session.commit()
|
||||
except IntegrityError:
|
||||
session.rollback()
|
||||
|
||||
try:
|
||||
initial = DB_VERSION if is_new else 100
|
||||
session.add(Version(key=DB_VERSION_INITIAL_KEY, value=initial))
|
||||
@@ -480,15 +469,6 @@ class Library:
|
||||
except IntegrityError:
|
||||
session.rollback()
|
||||
|
||||
# TODO: Remove this "Preferences" system.
|
||||
for pref in LibraryPrefs:
|
||||
with catch_warnings(record=True):
|
||||
try:
|
||||
session.add(Preferences(key=pref.name, value=pref.default))
|
||||
session.commit()
|
||||
except IntegrityError:
|
||||
session.rollback()
|
||||
|
||||
for field in FieldID:
|
||||
try:
|
||||
session.add(
|
||||
@@ -556,10 +536,9 @@ class Library:
|
||||
if loaded_db_version < 103:
|
||||
# changes: tags
|
||||
self.__apply_db103_migration(session)
|
||||
|
||||
# Convert file extension list to ts_ignore file, if a .ts_ignore file does not exist
|
||||
# TODO: do this in the migration step that will remove the preferences table
|
||||
self.migrate_sql_to_ts_ignore(library_dir)
|
||||
if loaded_db_version < 104:
|
||||
# changes: deletes preferences
|
||||
self.__apply_db104_migrations(session, library_dir)
|
||||
|
||||
# Update DB_VERSION
|
||||
if loaded_db_version < DB_VERSION:
|
||||
@@ -732,33 +711,30 @@ class Library:
|
||||
)
|
||||
session.rollback()
|
||||
|
||||
def migrate_sql_to_ts_ignore(self, library_dir: Path):
|
||||
def __apply_db104_migrations(self, session: Session, library_dir: Path):
|
||||
"""Migrate DB from DB_VERSION 103 to 104."""
|
||||
# Convert file extension list to ts_ignore file, if a .ts_ignore file does not exist
|
||||
self.__migrate_sql_to_ts_ignore(library_dir)
|
||||
session.execute(text("DROP TABLE preferences"))
|
||||
session.commit()
|
||||
|
||||
def __migrate_sql_to_ts_ignore(self, library_dir: Path):
|
||||
# Do not continue if existing '.ts_ignore' file is found
|
||||
if Path(library_dir / TS_FOLDER_NAME / IGNORE_NAME).exists():
|
||||
ts_ignore = library_dir / TS_FOLDER_NAME / IGNORE_NAME
|
||||
if Path(ts_ignore).exists():
|
||||
return
|
||||
|
||||
# Create blank '.ts_ignore' file
|
||||
ts_ignore_template = (
|
||||
Path(__file__).parents[3] / "resources/templates/ts_ignore_template_blank.txt"
|
||||
)
|
||||
ts_ignore = library_dir / TS_FOLDER_NAME / IGNORE_NAME
|
||||
try:
|
||||
shutil.copy2(ts_ignore_template, ts_ignore)
|
||||
except Exception as e:
|
||||
logger.error("[ERROR][Library] Could not generate '.ts_ignore' file!", error=e)
|
||||
|
||||
# Load legacy extension data
|
||||
extensions: list[str] = self.prefs(LibraryPrefs.EXTENSION_LIST) # pyright: ignore
|
||||
is_exclude_list: bool = self.prefs(LibraryPrefs.IS_EXCLUDE_LIST) # pyright: ignore
|
||||
with Session(self.engine) as session:
|
||||
extensions: list[str] = unwrap(
|
||||
session.scalar(text("SELECT value FROM preferences WHERE key = 'EXTENSION_LIST'"))
|
||||
)
|
||||
is_exclude_list: bool = unwrap(
|
||||
session.scalar(text("SELECT value FROM preferences WHERE key = 'IS_EXCLUDE_LIST'"))
|
||||
)
|
||||
|
||||
# Copy extensions to '.ts_ignore' file
|
||||
if ts_ignore.exists():
|
||||
with open(ts_ignore, "a") as f:
|
||||
prefix = ""
|
||||
if not is_exclude_list:
|
||||
prefix = "!"
|
||||
f.write("*\n")
|
||||
f.writelines([f"{prefix}*.{x.lstrip('.')}\n" for x in extensions])
|
||||
with open(ts_ignore, "w") as f:
|
||||
f.write(migrate_ext_list(extensions, is_exclude_list))
|
||||
|
||||
@property
|
||||
def default_fields(self) -> list[BaseField]:
|
||||
@@ -1856,19 +1832,20 @@ class Library:
|
||||
engine = sqlalchemy.inspect(self.engine)
|
||||
try:
|
||||
# "Version" table added in DB_VERSION 101
|
||||
if engine and engine.has_table("Version"):
|
||||
if engine and engine.has_table("versions"):
|
||||
version = session.scalar(select(Version).where(Version.key == key))
|
||||
assert version
|
||||
return version.value
|
||||
# NOTE: The "Preferences" table has been depreciated as of TagStudio 9.5.4
|
||||
# and is set to be removed in a future release.
|
||||
else:
|
||||
pref_version = session.scalar(
|
||||
select(Preferences).where(Preferences.key == DB_VERSION_LEGACY_KEY)
|
||||
return int(
|
||||
unwrap(
|
||||
session.scalar(
|
||||
text("SELECT value FROM preferences WHERE key == 'DB_VERSION'")
|
||||
)
|
||||
)
|
||||
)
|
||||
assert pref_version
|
||||
assert isinstance(pref_version.value, int)
|
||||
return pref_version.value
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
@@ -1886,60 +1863,10 @@ class Library:
|
||||
version.value = value
|
||||
session.add(version)
|
||||
session.commit()
|
||||
|
||||
# If a depreciated "Preferences" table is found, update the version value to be read
|
||||
# by older TagStudio versions.
|
||||
engine = sqlalchemy.inspect(self.engine)
|
||||
if engine and engine.has_table("Preferences"):
|
||||
pref = unwrap(
|
||||
session.scalar(
|
||||
select(Preferences).where(Preferences.key == DB_VERSION_LEGACY_KEY)
|
||||
)
|
||||
)
|
||||
pref.value = value # pyright: ignore
|
||||
session.add(pref)
|
||||
session.commit()
|
||||
except (IntegrityError, AssertionError) as e:
|
||||
logger.error("[Library][ERROR] Couldn't add default tag color namespaces", error=e)
|
||||
session.rollback()
|
||||
|
||||
# TODO: Remove this once the 'preferences' table is removed.
|
||||
@deprecated("Use `get_version() for version and `ts_ignore` system for extension exclusion.")
|
||||
def prefs(self, key: str | LibraryPrefs): # pyright: ignore[reportUnknownParameterType]
|
||||
# load given item from Preferences table
|
||||
with Session(self.engine) as session:
|
||||
if isinstance(key, LibraryPrefs):
|
||||
return unwrap(
|
||||
session.scalar(select(Preferences).where(Preferences.key == key.name))
|
||||
).value # pyright: ignore[reportUnknownVariableType]
|
||||
else:
|
||||
return unwrap(
|
||||
session.scalar(select(Preferences).where(Preferences.key == key))
|
||||
).value # pyright: ignore[reportUnknownVariableType]
|
||||
|
||||
# TODO: Remove this once the 'preferences' table is removed.
|
||||
@deprecated("Use `get_version() for version and `ts_ignore` system for extension exclusion.")
|
||||
def set_prefs(self, key: str | LibraryPrefs, value: Any) -> None: # pyright: ignore[reportExplicitAny]
|
||||
# set given item in Preferences table
|
||||
with Session(self.engine) as session:
|
||||
# load existing preference and update value
|
||||
stuff = session.scalars(select(Preferences))
|
||||
logger.info([x.key for x in list(stuff)])
|
||||
|
||||
pref: Preferences = unwrap(
|
||||
session.scalar(
|
||||
select(Preferences).where(
|
||||
Preferences.key == (key.name if isinstance(key, LibraryPrefs) else key)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
logger.info("loading pref", pref=pref, key=key, value=value)
|
||||
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 = {}
|
||||
|
||||
@@ -6,9 +6,8 @@ from datetime import datetime as dt
|
||||
from pathlib import Path
|
||||
from typing import override
|
||||
|
||||
from sqlalchemy import JSON, ForeignKey, ForeignKeyConstraint, Integer, event
|
||||
from sqlalchemy import ForeignKey, ForeignKeyConstraint, Integer, event
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from typing_extensions import deprecated
|
||||
|
||||
from tagstudio.core.constants import TAG_ARCHIVED, TAG_FAVORITE
|
||||
from tagstudio.core.library.alchemy.db import Base, PathType
|
||||
@@ -327,16 +326,6 @@ def slugify_field_key(mapper, connection, target): # pyright: ignore
|
||||
target.key = slugify(target.tag)
|
||||
|
||||
|
||||
# NOTE: The "Preferences" table has been depreciated as of TagStudio 9.5.4
|
||||
# and is set to be removed in a future release.
|
||||
@deprecated("Use `Version` for storing version, and `ts_ignore` system for file exclusion.")
|
||||
class Preferences(Base):
|
||||
__tablename__ = "preferences"
|
||||
|
||||
key: Mapped[str] = mapped_column(primary_key=True)
|
||||
value: Mapped[dict] = mapped_column(JSON, nullable=False)
|
||||
|
||||
|
||||
class Version(Base):
|
||||
__tablename__ = "versions"
|
||||
|
||||
|
||||
@@ -91,6 +91,23 @@ def ignore_to_glob(ignore_patterns: list[str]) -> list[str]:
|
||||
return glob_patterns
|
||||
|
||||
|
||||
def migrate_ext_list(exts: list[str], is_exclude_list: bool) -> str:
|
||||
# read template
|
||||
ts_ignore_template = (
|
||||
Path(__file__).parents[2] / "resources/templates/ts_ignore_template_blank.txt"
|
||||
)
|
||||
with open(ts_ignore_template) as f:
|
||||
out = f.read()
|
||||
|
||||
# actual conversion
|
||||
prefix = ""
|
||||
if not is_exclude_list:
|
||||
prefix = "!"
|
||||
out += "*\n"
|
||||
out += "\n".join([f"{prefix}*.{x.lstrip('.')}\n" for x in exts])
|
||||
return out
|
||||
|
||||
|
||||
class Ignore(metaclass=Singleton):
|
||||
"""Class for processing and managing glob-like file ignore file patterns."""
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ from pathlib import Path
|
||||
from typing import cast
|
||||
|
||||
import structlog
|
||||
import wcmatch.fnmatch as fnmatch
|
||||
from PySide6.QtCore import QObject, Qt, QThreadPool, Signal
|
||||
from PySide6.QtWidgets import (
|
||||
QApplication,
|
||||
@@ -24,18 +25,19 @@ from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from tagstudio.core.constants import (
|
||||
IGNORE_NAME,
|
||||
LEGACY_TAG_FIELD_IDS,
|
||||
TAG_ARCHIVED,
|
||||
TAG_FAVORITE,
|
||||
TAG_META,
|
||||
TS_FOLDER_NAME,
|
||||
)
|
||||
from tagstudio.core.enums import LibraryPrefs
|
||||
from tagstudio.core.library.alchemy import default_color_groups
|
||||
from tagstudio.core.library.alchemy.constants import SQL_FILENAME
|
||||
from tagstudio.core.library.alchemy.joins import TagParent
|
||||
from tagstudio.core.library.alchemy.library import Library as SqliteLibrary
|
||||
from tagstudio.core.library.alchemy.models import Entry, TagAlias
|
||||
from tagstudio.core.library.ignore import PATH_GLOB_FLAGS, Ignore, ignore_to_glob
|
||||
from tagstudio.core.library.json.library import Library as JsonLibrary
|
||||
from tagstudio.core.library.json.library import Tag as JsonTag
|
||||
from tagstudio.core.utils.types import unwrap
|
||||
@@ -72,8 +74,6 @@ class JsonMigrationModal(QObject):
|
||||
|
||||
self.old_entry_count: int = 0
|
||||
self.old_tag_count: int = 0
|
||||
self.old_ext_count: int = 0
|
||||
self.old_ext_type: bool = None # pyright: ignore[reportAttributeAccessIssue]
|
||||
|
||||
self.field_parity: bool = False
|
||||
self.path_parity: bool = False
|
||||
@@ -82,6 +82,7 @@ class JsonMigrationModal(QObject):
|
||||
self.subtag_parity: bool = False
|
||||
self.alias_parity: bool = False
|
||||
self.color_parity: bool = False
|
||||
self.ext_parity: bool = False
|
||||
|
||||
self.init_page_info()
|
||||
self.init_page_convert()
|
||||
@@ -129,8 +130,7 @@ class JsonMigrationModal(QObject):
|
||||
parent_tags_text: str = tab + Translations["json_migration.heading.parent_tags"]
|
||||
aliases_text: str = tab + Translations["json_migration.heading.aliases"]
|
||||
colors_text: str = tab + Translations["json_migration.heading.colors"]
|
||||
ext_text: str = Translations["json_migration.heading.file_extension_list"]
|
||||
ext_type_text: str = Translations["json_migration.heading.extension_list_type"]
|
||||
ext_parity_text: str = Translations["json_migration.heading.extensions"]
|
||||
desc_text: str = Translations["json_migration.description"]
|
||||
path_parity_text: str = tab + Translations["json_migration.heading.paths"]
|
||||
field_parity_text: str = tab + Translations["library_info.stats.fields"]
|
||||
@@ -145,7 +145,6 @@ class JsonMigrationModal(QObject):
|
||||
self.aliases_row: int = 7
|
||||
self.colors_row: int = 8
|
||||
self.ext_row: int = 9
|
||||
self.ext_type_row: int = 10
|
||||
|
||||
old_lib_container: QWidget = QWidget()
|
||||
old_lib_layout: QVBoxLayout = QVBoxLayout(old_lib_container)
|
||||
@@ -166,8 +165,7 @@ class JsonMigrationModal(QObject):
|
||||
self.old_content_layout.addWidget(QLabel(parent_tags_text), self.parent_tags_row, 0)
|
||||
self.old_content_layout.addWidget(QLabel(aliases_text), self.aliases_row, 0)
|
||||
self.old_content_layout.addWidget(QLabel(colors_text), self.colors_row, 0)
|
||||
self.old_content_layout.addWidget(QLabel(ext_text), self.ext_row, 0)
|
||||
self.old_content_layout.addWidget(QLabel(ext_type_text), self.ext_type_row, 0)
|
||||
self.old_content_layout.addWidget(QLabel(ext_parity_text), self.ext_row, 0)
|
||||
|
||||
old_entry_count: QLabel = QLabel()
|
||||
old_entry_count.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
@@ -187,10 +185,8 @@ class JsonMigrationModal(QObject):
|
||||
old_alias_value.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
old_color_value: QLabel = QLabel()
|
||||
old_color_value.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
old_ext_count: QLabel = QLabel()
|
||||
old_ext_count.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
old_ext_type: QLabel = QLabel()
|
||||
old_ext_type.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
old_ext_value: QLabel = QLabel()
|
||||
old_ext_value.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
|
||||
self.old_content_layout.addWidget(old_entry_count, self.entries_row, 1)
|
||||
self.old_content_layout.addWidget(old_path_value, self.path_row, 1)
|
||||
@@ -201,8 +197,7 @@ class JsonMigrationModal(QObject):
|
||||
self.old_content_layout.addWidget(old_subtag_value, self.parent_tags_row, 1)
|
||||
self.old_content_layout.addWidget(old_alias_value, self.aliases_row, 1)
|
||||
self.old_content_layout.addWidget(old_color_value, self.colors_row, 1)
|
||||
self.old_content_layout.addWidget(old_ext_count, self.ext_row, 1)
|
||||
self.old_content_layout.addWidget(old_ext_type, self.ext_type_row, 1)
|
||||
self.old_content_layout.addWidget(old_ext_value, self.ext_row, 1)
|
||||
|
||||
self.old_content_layout.addWidget(QLabel(), self.path_row, 2)
|
||||
self.old_content_layout.addWidget(QLabel(), self.fields_row, 2)
|
||||
@@ -211,6 +206,7 @@ class JsonMigrationModal(QObject):
|
||||
self.old_content_layout.addWidget(QLabel(), self.parent_tags_row, 2)
|
||||
self.old_content_layout.addWidget(QLabel(), self.aliases_row, 2)
|
||||
self.old_content_layout.addWidget(QLabel(), self.colors_row, 2)
|
||||
self.old_content_layout.addWidget(QLabel(), self.ext_row, 2)
|
||||
|
||||
old_lib_layout.addWidget(old_content_container)
|
||||
|
||||
@@ -233,8 +229,7 @@ class JsonMigrationModal(QObject):
|
||||
self.new_content_layout.addWidget(QLabel(parent_tags_text), self.parent_tags_row, 0)
|
||||
self.new_content_layout.addWidget(QLabel(aliases_text), self.aliases_row, 0)
|
||||
self.new_content_layout.addWidget(QLabel(colors_text), self.colors_row, 0)
|
||||
self.new_content_layout.addWidget(QLabel(ext_text), self.ext_row, 0)
|
||||
self.new_content_layout.addWidget(QLabel(ext_type_text), self.ext_type_row, 0)
|
||||
self.new_content_layout.addWidget(QLabel(ext_parity_text), self.ext_row, 0)
|
||||
|
||||
new_entry_count: QLabel = QLabel()
|
||||
new_entry_count.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
@@ -254,10 +249,8 @@ class JsonMigrationModal(QObject):
|
||||
alias_parity_value.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
new_color_value: QLabel = QLabel()
|
||||
new_color_value.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
new_ext_count: QLabel = QLabel()
|
||||
new_ext_count.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
new_ext_type: QLabel = QLabel()
|
||||
new_ext_type.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
ext_parity_value: QLabel = QLabel()
|
||||
ext_parity_value.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
|
||||
self.new_content_layout.addWidget(new_entry_count, self.entries_row, 1)
|
||||
self.new_content_layout.addWidget(path_parity_value, self.path_row, 1)
|
||||
@@ -268,8 +261,7 @@ class JsonMigrationModal(QObject):
|
||||
self.new_content_layout.addWidget(subtag_parity_value, self.parent_tags_row, 1)
|
||||
self.new_content_layout.addWidget(alias_parity_value, self.aliases_row, 1)
|
||||
self.new_content_layout.addWidget(new_color_value, self.colors_row, 1)
|
||||
self.new_content_layout.addWidget(new_ext_count, self.ext_row, 1)
|
||||
self.new_content_layout.addWidget(new_ext_type, self.ext_type_row, 1)
|
||||
self.new_content_layout.addWidget(ext_parity_value, self.ext_row, 1)
|
||||
|
||||
self.new_content_layout.addWidget(QLabel(), self.entries_row, 2)
|
||||
self.new_content_layout.addWidget(QLabel(), self.path_row, 2)
|
||||
@@ -281,7 +273,6 @@ class JsonMigrationModal(QObject):
|
||||
self.new_content_layout.addWidget(QLabel(), self.aliases_row, 2)
|
||||
self.new_content_layout.addWidget(QLabel(), self.colors_row, 2)
|
||||
self.new_content_layout.addWidget(QLabel(), self.ext_row, 2)
|
||||
self.new_content_layout.addWidget(QLabel(), self.ext_type_row, 2)
|
||||
|
||||
new_lib_layout.addWidget(new_content_container)
|
||||
|
||||
@@ -334,8 +325,6 @@ class JsonMigrationModal(QObject):
|
||||
# Update JSON UI
|
||||
self.update_json_entry_count(len(self.json_lib.entries))
|
||||
self.update_json_tag_count(len(self.json_lib.tags))
|
||||
self.update_json_ext_count(len(self.json_lib.ext_list))
|
||||
self.update_json_ext_type(self.json_lib.is_exclude_list)
|
||||
|
||||
self.migration_progress(skip_ui=skip_ui)
|
||||
self.is_migration_initialized = True
|
||||
@@ -429,6 +418,7 @@ class JsonMigrationModal(QObject):
|
||||
check_set.add(self.check_subtag_parity())
|
||||
check_set.add(self.check_alias_parity())
|
||||
check_set.add(self.check_color_parity())
|
||||
check_set.add(self.check_ignore_parity())
|
||||
if False not in check_set:
|
||||
yield Translations["json_migration.migration_complete"]
|
||||
else:
|
||||
@@ -455,6 +445,7 @@ class JsonMigrationModal(QObject):
|
||||
self.update_parity_value(self.parent_tags_row, self.subtag_parity)
|
||||
self.update_parity_value(self.aliases_row, self.alias_parity)
|
||||
self.update_parity_value(self.colors_row, self.color_parity)
|
||||
self.update_parity_value(self.ext_row, self.ext_parity)
|
||||
self.sql_lib.close()
|
||||
|
||||
def update_sql_value_ui(self, show_msg_box: bool = True):
|
||||
@@ -469,16 +460,6 @@ class JsonMigrationModal(QObject):
|
||||
len(self.sql_lib.tags),
|
||||
self.old_tag_count,
|
||||
)
|
||||
self.update_sql_value(
|
||||
self.ext_row,
|
||||
len(self.sql_lib.prefs(LibraryPrefs.EXTENSION_LIST)),
|
||||
self.old_ext_count,
|
||||
)
|
||||
self.update_sql_value(
|
||||
self.ext_type_row,
|
||||
self.sql_lib.prefs(LibraryPrefs.IS_EXCLUDE_LIST), # pyright: ignore[reportArgumentType]
|
||||
self.old_ext_type,
|
||||
)
|
||||
logger.info("Parity check complete!")
|
||||
if self.discrepancies:
|
||||
logger.warning("Discrepancies found:")
|
||||
@@ -510,16 +491,6 @@ class JsonMigrationModal(QObject):
|
||||
label: QLabel = self.old_content_layout.itemAtPosition(self.tags_row, 1).widget() # type:ignore
|
||||
label.setText(self.color_value_default(value))
|
||||
|
||||
def update_json_ext_count(self, value: int):
|
||||
self.old_ext_count = value
|
||||
label: QLabel = self.old_content_layout.itemAtPosition(self.ext_row, 1).widget() # type:ignore
|
||||
label.setText(self.color_value_default(value))
|
||||
|
||||
def update_json_ext_type(self, value: bool):
|
||||
self.old_ext_type = value
|
||||
label: QLabel = self.old_content_layout.itemAtPosition(self.ext_type_row, 1).widget() # type:ignore
|
||||
label.setText(self.color_value_default(value))
|
||||
|
||||
def update_sql_value(self, row: int, value: int | bool, old_value: int | bool):
|
||||
label: QLabel = self.new_content_layout.itemAtPosition(row, 1).widget() # type:ignore
|
||||
warning_icon: QLabel = self.new_content_layout.itemAtPosition(row, 2).widget() # type:ignore
|
||||
@@ -548,6 +519,28 @@ class JsonMigrationModal(QObject):
|
||||
color = green if old_value == new_value else red
|
||||
return str(f"<b><a style='color: {color}'>{new_value}</a></b>")
|
||||
|
||||
def assert_ignore_parity(self) -> None:
|
||||
compiled_pats = fnmatch.compile(
|
||||
ignore_to_glob(
|
||||
Ignore._load_ignore_file(
|
||||
unwrap(self.json_lib.library_dir) / TS_FOLDER_NAME / IGNORE_NAME
|
||||
)
|
||||
),
|
||||
PATH_GLOB_FLAGS,
|
||||
) # copied from Ignore.get_patterns since that method modifies singleton state
|
||||
path = self.json_lib.library_dir / "filename"
|
||||
for ext in self.json_lib.ext_list:
|
||||
assert compiled_pats.match(str(path / ext)) == self.json_lib.is_exclude_list
|
||||
assert compiled_pats.match(str(path / ".not_a_real_ext")) != self.json_lib.is_exclude_list
|
||||
|
||||
def check_ignore_parity(self) -> bool:
|
||||
try:
|
||||
self.assert_ignore_parity()
|
||||
self.ext_parity = True
|
||||
except AssertionError:
|
||||
self.ext_parity = False
|
||||
return self.ext_parity
|
||||
|
||||
def check_field_parity(self) -> bool:
|
||||
"""Check if all JSON field and tag data matches the new SQL data."""
|
||||
|
||||
@@ -671,9 +664,6 @@ class JsonMigrationModal(QObject):
|
||||
self.subtag_parity = True
|
||||
return self.subtag_parity
|
||||
|
||||
def check_ext_type(self) -> bool:
|
||||
return self.json_lib.is_exclude_list == self.sql_lib.prefs(LibraryPrefs.IS_EXCLUDE_LIST)
|
||||
|
||||
def check_alias_parity(self) -> bool:
|
||||
"""Check if all JSON aliases match the new SQL aliases."""
|
||||
with Session(self.sql_lib.engine) as session:
|
||||
|
||||
@@ -157,8 +157,6 @@
|
||||
"json_migration.heading.aliases": "Aliase:",
|
||||
"json_migration.heading.colors": "Farben:",
|
||||
"json_migration.heading.differ": "Diskrepanz",
|
||||
"json_migration.heading.extension_list_type": "Erweiterungslistentyp:",
|
||||
"json_migration.heading.file_extension_list": "Liste der Dateiendungen:",
|
||||
"json_migration.heading.match": "Übereinstimmend",
|
||||
"json_migration.heading.names": "Namen:",
|
||||
"json_migration.heading.parent_tags": "Übergeordnete Tags:",
|
||||
|
||||
@@ -157,8 +157,7 @@
|
||||
"json_migration.heading.aliases": "Aliases:",
|
||||
"json_migration.heading.colors": "Colors:",
|
||||
"json_migration.heading.differ": "Discrepancy",
|
||||
"json_migration.heading.extension_list_type": "Extension List Type:",
|
||||
"json_migration.heading.file_extension_list": "File Extension List:",
|
||||
"json_migration.heading.extensions": "Extensions:",
|
||||
"json_migration.heading.match": "Matched",
|
||||
"json_migration.heading.names": "Names:",
|
||||
"json_migration.heading.parent_tags": "Parent Tags:",
|
||||
|
||||
@@ -157,8 +157,6 @@
|
||||
"json_migration.heading.aliases": "Alias:",
|
||||
"json_migration.heading.colors": "Colores:",
|
||||
"json_migration.heading.differ": "Discrepancia",
|
||||
"json_migration.heading.extension_list_type": "Tipo de lista de extensión:",
|
||||
"json_migration.heading.file_extension_list": "Lista de extensiones de archivos:",
|
||||
"json_migration.heading.match": "Igualado",
|
||||
"json_migration.heading.names": "Nombres:",
|
||||
"json_migration.heading.parent_tags": "Etiquetas principales:",
|
||||
|
||||
@@ -140,8 +140,6 @@
|
||||
"json_migration.heading.aliases": "Mga alyas:",
|
||||
"json_migration.heading.colors": "Mga kulay:",
|
||||
"json_migration.heading.differ": "May pagkakaiba",
|
||||
"json_migration.heading.extension_list_type": "Uri ng Listahan ng Extension:",
|
||||
"json_migration.heading.file_extension_list": "Listahan ng Mga File Extension:",
|
||||
"json_migration.heading.match": "Tumutugma",
|
||||
"json_migration.heading.names": "Mga pangalan:",
|
||||
"json_migration.heading.parent_tags": "Mga parent tag:",
|
||||
|
||||
@@ -157,8 +157,6 @@
|
||||
"json_migration.heading.aliases": "Alias :",
|
||||
"json_migration.heading.colors": "Couleurs :",
|
||||
"json_migration.heading.differ": "Divergence",
|
||||
"json_migration.heading.extension_list_type": "Type de liste d'extension :",
|
||||
"json_migration.heading.file_extension_list": "Liste des extensions de fichiers :",
|
||||
"json_migration.heading.match": "Correspondant",
|
||||
"json_migration.heading.names": "Noms :",
|
||||
"json_migration.heading.parent_tags": "Tags Parents :",
|
||||
|
||||
@@ -157,8 +157,6 @@
|
||||
"json_migration.heading.aliases": "Áljelek:",
|
||||
"json_migration.heading.colors": "Színek:",
|
||||
"json_migration.heading.differ": "Eltérés",
|
||||
"json_migration.heading.extension_list_type": "Kiterjesztési lista típusa:",
|
||||
"json_migration.heading.file_extension_list": "Fájlkiterjesztési lista:",
|
||||
"json_migration.heading.match": "Egységesítve",
|
||||
"json_migration.heading.names": "Nevek:",
|
||||
"json_migration.heading.parent_tags": "Szülőcímkék:",
|
||||
|
||||
@@ -157,8 +157,6 @@
|
||||
"json_migration.heading.aliases": "Alias:",
|
||||
"json_migration.heading.colors": "Colori:",
|
||||
"json_migration.heading.differ": "Discrepanze",
|
||||
"json_migration.heading.extension_list_type": "Tipo di Lista di Entensioni:",
|
||||
"json_migration.heading.file_extension_list": "Elenco Estensioni dei File:",
|
||||
"json_migration.heading.match": "Abbinato",
|
||||
"json_migration.heading.names": "Nomi:",
|
||||
"json_migration.heading.parent_tags": "Etichette Genitore:",
|
||||
|
||||
@@ -157,8 +157,6 @@
|
||||
"json_migration.heading.aliases": "エイリアス:",
|
||||
"json_migration.heading.colors": "色:",
|
||||
"json_migration.heading.differ": "差異",
|
||||
"json_migration.heading.extension_list_type": "拡張子リストの種類:",
|
||||
"json_migration.heading.file_extension_list": "ファイルの拡張子リスト:",
|
||||
"json_migration.heading.match": "一致",
|
||||
"json_migration.heading.names": "名前:",
|
||||
"json_migration.heading.parent_tags": "親タグ:",
|
||||
|
||||
@@ -148,8 +148,6 @@
|
||||
"json_migration.heading.aliases": "Alternative navn:",
|
||||
"json_migration.heading.colors": "Farger:",
|
||||
"json_migration.heading.differ": "Avvik",
|
||||
"json_migration.heading.extension_list_type": "Type av Utvidelsesliste:",
|
||||
"json_migration.heading.file_extension_list": "Filutvidelse Liste:",
|
||||
"json_migration.heading.match": "Matchet",
|
||||
"json_migration.heading.names": "Navn:",
|
||||
"json_migration.heading.parent_tags": "Overordnede Etiketter:",
|
||||
|
||||
@@ -139,8 +139,6 @@
|
||||
"json_migration.heading.aliases": "Zastępcze nazwy:",
|
||||
"json_migration.heading.colors": "Kolory:",
|
||||
"json_migration.heading.differ": "Niezgodność",
|
||||
"json_migration.heading.extension_list_type": "Typ listy rozszerzeń:",
|
||||
"json_migration.heading.file_extension_list": "Lista rozszerzeń plików:",
|
||||
"json_migration.heading.match": "Dopasowane",
|
||||
"json_migration.heading.names": "Nazwy:",
|
||||
"json_migration.heading.parent_tags": "Tagi nadrzędne:",
|
||||
|
||||
@@ -136,8 +136,6 @@
|
||||
"json_migration.heading.aliases": "Pseudônimos:",
|
||||
"json_migration.heading.colors": "Cores:",
|
||||
"json_migration.heading.differ": "Discrepância",
|
||||
"json_migration.heading.extension_list_type": "Tipo de Lista de Extensão:",
|
||||
"json_migration.heading.file_extension_list": "Lista de Extensão de Ficheiro:",
|
||||
"json_migration.heading.match": "Combinado",
|
||||
"json_migration.heading.names": "Nomes:",
|
||||
"json_migration.heading.parent_tags": "Tags Pai:",
|
||||
|
||||
@@ -157,8 +157,6 @@
|
||||
"json_migration.heading.aliases": "Pseudônimos:",
|
||||
"json_migration.heading.colors": "Cores:",
|
||||
"json_migration.heading.differ": "Discrepância",
|
||||
"json_migration.heading.extension_list_type": "Lista dos tipos de Extensão:",
|
||||
"json_migration.heading.file_extension_list": "Lista de Extensão de Arquivo:",
|
||||
"json_migration.heading.match": "Correspondido",
|
||||
"json_migration.heading.names": "Nomes:",
|
||||
"json_migration.heading.parent_tags": "Tags Pai:",
|
||||
|
||||
@@ -137,8 +137,6 @@
|
||||
"json_migration.heading.aliases": "Andrnamae:",
|
||||
"json_migration.heading.colors": "Varge:",
|
||||
"json_migration.heading.differ": "Tchigauzma",
|
||||
"json_migration.heading.extension_list_type": "Fal fu taksanting tumam:",
|
||||
"json_migration.heading.file_extension_list": "Tumam fu mlafufal:",
|
||||
"json_migration.heading.match": "Finnajena sama",
|
||||
"json_migration.heading.names": "Namae:",
|
||||
"json_migration.heading.parent_tags": "Atama festaretol:",
|
||||
|
||||
@@ -148,8 +148,6 @@
|
||||
"json_migration.heading.aliases": "Псевдонимы:",
|
||||
"json_migration.heading.colors": "Цвета:",
|
||||
"json_migration.heading.differ": "Несоответствие",
|
||||
"json_migration.heading.extension_list_type": "Тип списка расширений:",
|
||||
"json_migration.heading.file_extension_list": "Список расширений файлов:",
|
||||
"json_migration.heading.match": "Совпало",
|
||||
"json_migration.heading.names": "Имена:",
|
||||
"json_migration.heading.parent_tags": "Родительские теги:",
|
||||
|
||||
@@ -157,8 +157,6 @@
|
||||
"json_migration.heading.aliases": "மாற்றுப்பெயர்கள்:",
|
||||
"json_migration.heading.colors": "நிறங்கள்:",
|
||||
"json_migration.heading.differ": "முரண்பாடு",
|
||||
"json_migration.heading.extension_list_type": "நீட்டிப்பு பட்டியல் வகை:",
|
||||
"json_migration.heading.file_extension_list": "கோப்பு நீட்டிப்பு பட்டியல்:",
|
||||
"json_migration.heading.match": "பொருந்தியது",
|
||||
"json_migration.heading.names": "பெயர்கள்:",
|
||||
"json_migration.heading.parent_tags": "பெற்றோர் குறிச்சொற்கள்:",
|
||||
|
||||
@@ -154,7 +154,6 @@
|
||||
"json_migration.heading.aliases": "nimi ante:",
|
||||
"json_migration.heading.colors": "kule:",
|
||||
"json_migration.heading.differ": "ante ike",
|
||||
"json_migration.heading.file_extension_list": "kulupu pi namako lipu:",
|
||||
"json_migration.heading.match": "sama",
|
||||
"json_migration.heading.names": "nimi:",
|
||||
"json_migration.heading.parent_tags": "poki mama:",
|
||||
|
||||
@@ -136,8 +136,6 @@
|
||||
"json_migration.heading.aliases": "Takma Adlar:",
|
||||
"json_migration.heading.colors": "Renkler:",
|
||||
"json_migration.heading.differ": "Uyuşmazlık",
|
||||
"json_migration.heading.extension_list_type": "Uzantı Listesi Türü:",
|
||||
"json_migration.heading.file_extension_list": "Dosya Uzantı Listesi:",
|
||||
"json_migration.heading.match": "Eşleşti",
|
||||
"json_migration.heading.names": "Adlar:",
|
||||
"json_migration.heading.parent_tags": "Üst Etiketler:",
|
||||
|
||||
@@ -152,8 +152,6 @@
|
||||
"json_migration.heading.aliases": "别名:",
|
||||
"json_migration.heading.colors": "颜色:",
|
||||
"json_migration.heading.differ": "差异",
|
||||
"json_migration.heading.extension_list_type": "扩展名列表类型:",
|
||||
"json_migration.heading.file_extension_list": "文件扩展名列表:",
|
||||
"json_migration.heading.match": "已匹配",
|
||||
"json_migration.heading.names": "名字:",
|
||||
"json_migration.heading.parent_tags": "上级标签:",
|
||||
|
||||
@@ -156,8 +156,6 @@
|
||||
"json_migration.heading.aliases": "別名:",
|
||||
"json_migration.heading.colors": "顏色:",
|
||||
"json_migration.heading.differ": "差異",
|
||||
"json_migration.heading.extension_list_type": "副檔名清單類型:",
|
||||
"json_migration.heading.file_extension_list": "檔案副檔名清單:",
|
||||
"json_migration.heading.match": "已一致",
|
||||
"json_migration.heading.names": "名稱:",
|
||||
"json_migration.heading.parent_tags": "父標籤:",
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ from tempfile import TemporaryDirectory
|
||||
|
||||
import pytest
|
||||
|
||||
from tagstudio.core.enums import LibraryPrefs
|
||||
from tagstudio.core.constants import IGNORE_NAME
|
||||
from tagstudio.core.library.alchemy.library import Library
|
||||
from tagstudio.core.library.refresh import RefreshTracker
|
||||
from tagstudio.core.utils.types import unwrap
|
||||
@@ -20,15 +20,14 @@ CWD = Path(__file__).parent
|
||||
def test_refresh_new_files(library: Library, exclude_mode: bool):
|
||||
library_dir = unwrap(library.library_dir)
|
||||
# Given
|
||||
library.set_prefs(LibraryPrefs.IS_EXCLUDE_LIST, exclude_mode)
|
||||
library.set_prefs(LibraryPrefs.EXTENSION_LIST, [".md"])
|
||||
registry = RefreshTracker(library=library)
|
||||
library.included_files.clear()
|
||||
(library_dir / "FOO.MD").touch()
|
||||
(library_dir / IGNORE_NAME).write_text("*.md" if exclude_mode else "*\n!*.md")
|
||||
|
||||
# Test if the single file was added
|
||||
list(registry.refresh_dir(library_dir, force_internal_tools=True))
|
||||
assert registry.files_not_in_library == [Path("FOO.MD")]
|
||||
assert set(registry.files_not_in_library) == set([Path(IGNORE_NAME), Path("FOO.MD")])
|
||||
|
||||
|
||||
@pytest.mark.parametrize("library", [TemporaryDirectory()], indirect=True)
|
||||
|
||||
@@ -46,9 +46,9 @@ def test_library_migrations(path: str):
|
||||
try:
|
||||
status = library.open_library(library_dir=temp_path)
|
||||
library.close()
|
||||
shutil.rmtree(temp_path)
|
||||
assert status.success
|
||||
except Exception as e:
|
||||
library.close()
|
||||
shutil.rmtree(temp_path)
|
||||
raise (e)
|
||||
finally:
|
||||
shutil.rmtree(temp_path)
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
from pathlib import Path
|
||||
from time import time
|
||||
|
||||
from tagstudio.core.enums import LibraryPrefs
|
||||
from tagstudio.qt.mixed.migration_modal import JsonMigrationModal
|
||||
|
||||
CWD = Path(__file__)
|
||||
@@ -43,10 +42,4 @@ def test_json_migration():
|
||||
assert modal.check_color_parity()
|
||||
|
||||
# Extension Filter List ====================================================
|
||||
# Count
|
||||
assert len(modal.json_lib.ext_list) == len(modal.sql_lib.prefs(LibraryPrefs.EXTENSION_LIST))
|
||||
# List Type
|
||||
assert modal.check_ext_type()
|
||||
# No Leading Dot
|
||||
for ext in modal.sql_lib.prefs(LibraryPrefs.EXTENSION_LIST): # pyright: ignore[reportUnknownVariableType]
|
||||
assert ext[0] != "."
|
||||
modal.assert_ignore_parity()
|
||||
|
||||
@@ -10,7 +10,6 @@ from tempfile import TemporaryDirectory
|
||||
import pytest
|
||||
import structlog
|
||||
|
||||
from tagstudio.core.enums import DefaultEnum, LibraryPrefs
|
||||
from tagstudio.core.library.alchemy.enums import BrowsingState
|
||||
from tagstudio.core.library.alchemy.fields import (
|
||||
FieldID, # pyright: ignore[reportPrivateUsage]
|
||||
@@ -199,11 +198,6 @@ def test_search_library_case_insensitive(library: Library):
|
||||
assert results[0] == entry.id
|
||||
|
||||
|
||||
def test_preferences(library: Library):
|
||||
for pref in LibraryPrefs:
|
||||
assert library.prefs(pref) == pref.default
|
||||
|
||||
|
||||
def test_remove_entry_field(library: Library, entry_full: Entry):
|
||||
title_field = entry_full.text_fields[0]
|
||||
|
||||
@@ -393,24 +387,6 @@ def test_update_field_order(library: Library, entry_full: Entry):
|
||||
assert entry.text_fields[1].value == "second"
|
||||
|
||||
|
||||
def test_library_prefs_multiple_identical_vals():
|
||||
# check the preferences are inherited from DefaultEnum
|
||||
assert issubclass(LibraryPrefs, DefaultEnum)
|
||||
|
||||
# create custom settings with identical values
|
||||
class TestPrefs(DefaultEnum):
|
||||
FOO = 1
|
||||
BAR = 1
|
||||
|
||||
assert TestPrefs.FOO.default == 1
|
||||
assert TestPrefs.BAR.default == 1
|
||||
assert TestPrefs.BAR.name == "BAR"
|
||||
|
||||
# accessing .value should raise exception
|
||||
with pytest.raises(AttributeError):
|
||||
assert TestPrefs.BAR.value
|
||||
|
||||
|
||||
def test_path_search_ilike(library: Library):
|
||||
results = library.search_library(BrowsingState.from_path("bar.md"), page_size=500)
|
||||
assert results.total_count == 1
|
||||
|
||||
Reference in New Issue
Block a user