Storing tags as well as tag_files in tags config.

This commit is contained in:
Roland 2023-03-27 14:45:31 -06:00
parent 5bd1e39f0e
commit d222ba4d32
No known key found for this signature in database
GPG key ID: 9D6DBD3ACF11AB93
2 changed files with 46 additions and 15 deletions

View file

@ -5,9 +5,10 @@ from cryptography.exceptions import InvalidTag
from sqlalchemy import Column, Integer, String, ForeignKey, BigInteger
from sqlalchemy.orm import relationship, Session
from wrolpi.common import ModelHelper, Base, logger, ConfigFile, get_media_directory
from wrolpi.common import ModelHelper, Base, logger, ConfigFile, get_media_directory, background_task
from wrolpi.db import optional_session
from wrolpi.errors import UnknownTag, UsedTag
from wrolpi.vars import PYTEST
logger = logger.getChild(__name__)
@ -55,7 +56,9 @@ class Tag(ModelHelper, Base):
session.add(tag_file)
session.flush([tag_file])
session.commit()
get_tags_config().save_tags(session)
# Save changes to config.
schedule_save(session)
return tag_file
@optional_session
@ -73,7 +76,9 @@ class Tag(ModelHelper, Base):
if tag_file:
session.delete(tag_file)
session.commit()
get_tags_config().save_tags(session)
# Save changes to config.
schedule_save(session)
else:
logger.warning(f'Could not find tag_file for FileGroup.id={file_group.id}/Tag.id={self.id=}')
@ -89,17 +94,18 @@ class TagsConfig(ConfigFile):
width = 500
default_config = dict(
tag_files=list(),
tags=list(),
)
@property
def tags(self) -> list:
return self._config['tags']
def tag_files(self) -> list:
return self._config['tag_files']
@tags.setter
def tags(self, value):
@tag_files.setter
def tag_files(self, value):
value = sorted(value, key=lambda i: (i[0].lower(), i[1]))
self.update({'tags': value})
self.update({'tag_files': value})
def save_tags(self, session: Session):
media_directory = get_media_directory()
@ -109,13 +115,21 @@ class TagsConfig(ConfigFile):
.filter(TagFile.tag_id == Tag.id, TagFile.file_group_id == FileGroup.id) \
.order_by(FileGroup.primary_path)
tags = []
tags = dict()
tag_rows = session.query(Tag)
for tag in tag_rows:
tags[tag.name] = dict(color=tag.color)
tag_files = []
for tag, _, file_group in results:
value = [tag.name, str(file_group.primary_path.relative_to(media_directory))]
tags.append(value)
tag_files.append(value)
# Write tags to the config.
self.tags = tags
# Write to the config.
self.update({
'tag_files': tag_files,
'tags': tags,
})
TAGS_CONFIG: TagsConfig = TagsConfig(global_=True)
@ -168,3 +182,14 @@ def delete_tag(name: str, session: Session = None):
session.delete(tag)
session.commit()
def schedule_save(session: Session):
"""Schedule a background task to save all TagFiles to the config file. If testing, save synchronously."""
if PYTEST:
get_tags_config().save_tags(session)
else:
async def _():
get_tags_config().save_tags(session)
background_task(_())

View file

@ -1,8 +1,9 @@
import pytest
from wrolpi import tags
from wrolpi.files import lib as files_lib
from wrolpi.files.models import FileGroup
from wrolpi.tags import TagFile, get_tags_config
from wrolpi.tags import TagFile
@pytest.mark.asyncio
@ -63,6 +64,11 @@ async def test_tags_config_(test_session, test_directory, tag_factory, example_p
video: FileGroup = FileGroup.find_by_path(video_file, test_session)
tag1 = tag_factory()
tag2 = tag_factory()
test_session.commit()
tags.schedule_save(test_session)
assert tag1.name in test_tags_config.read_text()
assert tag2.name in test_tags_config.read_text()
video.add_tag(tag1)
assert str(video_file.relative_to(test_directory)) in test_tags_config.read_text()
@ -89,8 +95,8 @@ async def test_tags_config_(test_session, test_directory, tag_factory, example_p
assert str(example_pdf.relative_to(test_directory)) not in test_tags_config.read_text()
# No more tags.
tags_config = get_tags_config()
assert isinstance(tags_config.tags, list) and len(tags_config.tags) == 0
tags_config = tags.get_tags_config()
assert isinstance(tags_config.tag_files, list) and len(tags_config.tag_files) == 0
# Removing non-existent tag does not error.
video.remove_tag(tag1)