Skip to content

Commit 30cbcad

Browse files
committed
create Preferences DB table
1 parent 040d127 commit 30cbcad

File tree

5 files changed

+70
-24
lines changed

5 files changed

+70
-24
lines changed

tagstudio/src/core/constants.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from enum import Enum, StrEnum
2+
3+
14
VERSION: str = "9.3.2" # Major.Minor.Patch
25
VERSION_BRANCH: str = "" # Usually "" or "Pre-Release"
36

@@ -126,3 +129,8 @@
126129

127130
TAG_FAVORITE = 1
128131
TAG_ARCHIVED = 0
132+
133+
134+
class PREFS(Enum):
135+
IS_EXCLUDE_LIST = False
136+
EXTENSION_LIST: list[str] = []

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

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
TextField,
2525
)
2626
from .joins import TagField, TagSubtag
27-
from .models import Entry, Tag, TagAlias
28-
from ...constants import TS_FOLDER_NAME, TAG_ARCHIVED, TAG_FAVORITE
27+
from .models import Entry, Preferences, Tag, TagAlias
28+
from ...constants import PREFS, TS_FOLDER_NAME, TAG_ARCHIVED, TAG_FAVORITE
2929

3030
LIBRARY_FILENAME: str = "ts_library.sqlite"
3131

@@ -77,8 +77,6 @@ class Library:
7777
dupe_files: list[str]
7878
engine: Engine | None
7979
dupe_entries: list[Entry] # TODO
80-
ext_list: list[str] # TODO
81-
is_exclude_list: bool # TODO
8280

8381
def __init__(self):
8482
self.clear_internal_vars()
@@ -99,8 +97,7 @@ def open_library(self, library_dir: Path | str) -> None:
9997

10098
logger.info("opening library", connection_string=connection_string)
10199
self.engine = create_engine(connection_string)
102-
session = Session(self.engine)
103-
with session.begin():
100+
with Session(self.engine) as session:
104101
make_tables(self.engine)
105102

106103
tags = get_default_tags()
@@ -109,7 +106,15 @@ def open_library(self, library_dir: Path | str) -> None:
109106
session.commit()
110107
except IntegrityError:
111108
# default tags may exist already
112-
pass
109+
session.rollback()
110+
111+
for pref in PREFS:
112+
try:
113+
session.add(Preferences(key=pref.name, value=pref.value))
114+
session.commit()
115+
except IntegrityError:
116+
logger.error("pref already exists", pref=pref)
117+
session.rollback()
113118

114119
def delete_item(self, item):
115120
logger.info("deleting item", item=item)
@@ -736,3 +741,22 @@ def mirror_entry_fields(self, items: list):
736741

737742
def merge_dupe_entries(self):
738743
logger.error("merge_dupe_entries to be implemented")
744+
745+
def prefs(self, key: PREFS) -> Any:
746+
# load given item from Preferences table
747+
with Session(self.engine) as session:
748+
return session.scalar(
749+
select(Preferences).where(Preferences.key == key.name)
750+
).value
751+
752+
def set_prefs(self, key: PREFS, value: Any) -> None:
753+
# set given item in Preferences table
754+
with Session(self.engine) as session:
755+
# load existing preference and update value
756+
pref = session.scalar(
757+
select(Preferences).where(Preferences.key == key.name)
758+
)
759+
pref.value = value
760+
session.add(pref)
761+
session.commit()
762+
# TODO - try/except

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from pathlib import Path
2-
from typing import Optional
2+
from typing import Any, Optional
33

4-
from sqlalchemy import ForeignKey
4+
from sqlalchemy import JSON, ForeignKey
55
from sqlalchemy.orm import Mapped, mapped_column, relationship
66

77
from .db import Base
@@ -183,3 +183,15 @@ def remove_tag(self, tag: Tag, field: TagBoxField | None = None) -> None:
183183

184184
for tag_box_field in self.tag_box_fields:
185185
tag_box_field.tags.remove(tag)
186+
187+
188+
class Preferences(Base):
189+
__tablename__ = "preferences"
190+
191+
key: Mapped[str] = mapped_column(primary_key=True)
192+
value: Mapped[dict] = mapped_column(JSON, nullable=False)
193+
194+
def __init__(self, key: str, value: Any) -> None:
195+
self.key = key
196+
self.value = value
197+
super().__init__()

tagstudio/src/qt/modals/file_extension.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
from src.core.library import Library
2121
from src.qt.widgets.panel import PanelWidget
22+
from src.core.constants import PREFS
2223

2324

2425
class FileExtensionItemDelegate(QStyledItemDelegate):
@@ -43,7 +44,7 @@ def __init__(self, library: "Library"):
4344
self.root_layout.setContentsMargins(6, 6, 6, 6)
4445

4546
# Create Table Widget --------------------------------------------------
46-
self.table = QTableWidget(len(self.lib.ext_list), 1)
47+
self.table = QTableWidget(len(self.lib.prefs(PREFS.EXTENSION_LIST)), 1)
4748
self.table.horizontalHeader().setVisible(False)
4849
self.table.verticalHeader().setVisible(False)
4950
self.table.horizontalHeader().setStretchLastSection(True)
@@ -65,9 +66,12 @@ def __init__(self, library: "Library"):
6566
self.mode_label.setText("List Mode:")
6667
self.mode_combobox = QComboBox()
6768
self.mode_combobox.setEditable(False)
68-
self.mode_combobox.addItem("Exclude")
6969
self.mode_combobox.addItem("Include")
70-
self.mode_combobox.setCurrentIndex(0 if self.lib.is_exclude_list else 1)
70+
self.mode_combobox.addItem("Exclude")
71+
72+
is_exclude_list = int(bool(self.lib.prefs(PREFS.IS_EXCLUDE_LIST)))
73+
74+
self.mode_combobox.setCurrentIndex(is_exclude_list)
7175
self.mode_combobox.currentIndexChanged.connect(
7276
lambda i: self.update_list_mode(i)
7377
)
@@ -91,23 +95,23 @@ def update_list_mode(self, mode: int):
9195
9296
Args:
9397
mode (int): The list mode, given by the index of the mode inside
94-
the mode combobox. 0 for "Exclude", 1 for "Include".
98+
the mode combobox. True for "Exclude", False for "Include".
9599
"""
96-
if mode == 0:
97-
self.lib.is_exclude_list = True
98-
elif mode == 1:
99-
self.lib.is_exclude_list = False
100+
self.lib.set_prefs(PREFS.IS_EXCLUDE_LIST, bool(mode))
100101

101102
def refresh_list(self):
102-
for i, ext in enumerate(self.lib.ext_list):
103+
for i, ext in enumerate(self.lib.prefs(PREFS.EXTENSION_LIST)):
103104
self.table.setItem(i, 0, QTableWidgetItem(ext))
104105

105106
def add_item(self):
106107
self.table.insertRow(self.table.rowCount())
107108

108109
def save(self):
109-
self.lib.ext_list.clear()
110+
extensions = []
110111
for i in range(self.table.rowCount()):
111112
ext = self.table.item(i, 0)
112-
if ext and ext.text():
113-
self.lib.ext_list.append(ext.text().lower())
113+
if ext and ext.text().strip():
114+
extensions.append(ext.text().strip().lower())
115+
116+
# save preference
117+
self.lib.set_prefs(PREFS.EXTENSION_LIST, extensions)

tagstudio/src/qt/ts_qt.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,7 @@ def start(self) -> None:
367367
edit_menu.addSeparator()
368368

369369
manage_file_extensions_action = QAction("Manage File Extensions", menu_bar)
370-
manage_file_extensions_action.triggered.connect(
371-
lambda: self.show_file_extension_modal()
372-
)
370+
manage_file_extensions_action.triggered.connect(self.show_file_extension_modal)
373371
edit_menu.addAction(manage_file_extensions_action)
374372

375373
tag_database_action = QAction("Manage Tags", menu_bar)

0 commit comments

Comments
 (0)