From d222ba4d32e30175138c9ed635bb64efce239b9f Mon Sep 17 00:00:00 2001 From: Roland Date: Mon, 27 Mar 2023 14:45:31 -0600 Subject: [PATCH] Storing tags as well as tag_files in tags config. --- wrolpi/tags.py | 49 ++++++++++++++++++++++++++++++---------- wrolpi/test/test_tags.py | 12 +++++++--- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/wrolpi/tags.py b/wrolpi/tags.py index bfad2222..070306ee 100644 --- a/wrolpi/tags.py +++ b/wrolpi/tags.py @@ -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(_()) diff --git a/wrolpi/test/test_tags.py b/wrolpi/test/test_tags.py index 1f6ac565..aa16b413 100644 --- a/wrolpi/test/test_tags.py +++ b/wrolpi/test/test_tags.py @@ -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)