refactor!: change layout; import and build change

Fixes: #200
Fixes: #365
Fixes: #512
Fixes: #800

fix(pyproject): resolve mix-up of mypy and pytest

chore(ci): remove legacy scripts

chore: format with new mypy rules; fix translation test

wip(ci/mypy): remove config flag

fix(pyinstaller): use correct dict access

fix(resources): usage in ts_qt.py

feat(nix/package): validate tests with pytest hook

fix(nix/package): remove old dependency patch

feat(nix): support Darwin

fix(nix/package): move check deps to checkInputs

fix(nix/shell): typo

fix(nix/shell): correctly wrap Python with Qt args

fix(pyproject): specify mypy-extensions

feat(nix/package): provide pillow-jxl-plugin

nix(nix/package): split into multiple files, allow overriding of JXL and vtf2img

fix(nix/shell): provide FFmpeg on runtime

feat(flake): output pillow-jxl-plugin and vtf2img

fix(nix/package): load pipewire

feat(nix/package): run tests on pillow-jxl-plugin

fix: remove extra noqa comment

docs: update installation docs

docs: shrink table size on docs site

nit(nix/package): pipewire not needed in buildInputs

docs: update commands, environment, setup

fix: use consistent possessives

chore: format with prettier, add ignore flags

fix(pyinstaller): consume from pyproject

Revert "fix(pyinstaller): consume from pyproject"

This reverts commit 398cd4e5630a3e83d22d15286d7ac59b4c07c5d6.

refactor: use icon from resource manager

Also fixes incorrect path currently used in ts_qt.py.

nix(pyinstaller): replace use of sys.platform with platform.system

docs: add build section

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
This commit is contained in:
Xarvex
2025-03-06 20:34:38 -06:00
parent 226d18e743
commit 55bc7aac88
160 changed files with 1944 additions and 1861 deletions

View File

@@ -9,9 +9,9 @@ CWD = Path(__file__).parent
# this needs to be above `src` imports
sys.path.insert(0, str(CWD.parent))
from src.core.library import Entry, Library, Tag
from src.core.library import alchemy as backend
from src.qt.ts_qt import QtDriver
from tagstudio.core.library.alchemy.library import Library
from tagstudio.core.library.alchemy.models import Entry, Tag
from tagstudio.qt.ts_qt import QtDriver
@pytest.fixture
@@ -137,8 +137,8 @@ def qt_driver(qtbot, library):
open = Path(tmp_dir)
ci = True
with patch("src.qt.ts_qt.Consumer"), patch("src.qt.ts_qt.CustomRunnable"):
driver = QtDriver(backend, Args())
with patch("tagstudio.qt.ts_qt.Consumer"), patch("tagstudio.qt.ts_qt.CustomRunnable"):
driver = QtDriver(Args())
driver.main_window = Mock()
driver.preview_panel = Mock()

View File

@@ -1,7 +1,7 @@
from pathlib import Path
from src.core.library import Entry
from src.core.utils.dupe_files import DupeRegistry
from tagstudio.core.library.alchemy.models import Entry
from tagstudio.core.utils.dupe_files import DupeRegistry
CWD = Path(__file__).parent

View File

@@ -1,4 +1,4 @@
from src.qt.modals.folders_to_tags import folders_to_tags
from tagstudio.qt.modals.folders_to_tags import folders_to_tags
def test_folders_to_tags(library):

View File

@@ -2,9 +2,10 @@ from pathlib import Path
from tempfile import TemporaryDirectory
import pytest
from src.core.library import Library
from src.core.library.alchemy.enums import FilterState
from src.core.utils.missing_files import MissingRegistry
from tagstudio.core.library.alchemy.enums import FilterState
from tagstudio.core.library.alchemy.library import Library
from tagstudio.core.utils.missing_files import MissingRegistry
CWD = Path(__file__).parent

View File

@@ -2,8 +2,9 @@ from pathlib import Path
from tempfile import TemporaryDirectory
import pytest
from src.core.enums import LibraryPrefs
from src.core.utils.refresh_dir import RefreshDirTracker
from tagstudio.core.enums import LibraryPrefs
from tagstudio.core.utils.refresh_dir import RefreshDirTracker
CWD = Path(__file__).parent

View File

@@ -3,8 +3,8 @@
# from tempfile import TemporaryDirectory
# import pytest
# from src.core.enums import MacroID
# from src.core.library.alchemy.fields import _FieldID
# from tagstudio.core.enums import MacroID
# from tagstudio.core.library.alchemy.fields import _FieldID
# @pytest.mark.parametrize("library", [TemporaryDirectory()], indirect=True)

View File

@@ -1,6 +1,6 @@
from src.core.library.alchemy.models import Tag
from src.qt.modals.build_tag import BuildTagPanel
from src.qt.translations import Translations
from tagstudio.core.library.alchemy.models import Tag
from tagstudio.qt.modals.build_tag import BuildTagPanel
from tagstudio.qt.translations import Translations
def test_build_tag_panel_add_sub_tag_callback(library, generate_tag):

View File

@@ -1,4 +1,4 @@
from src.qt.widgets.preview_panel import PreviewPanel
from tagstudio.qt.widgets.preview_panel import PreviewPanel
def test_update_selection_empty(qt_driver, library):

View File

@@ -1,6 +1,7 @@
from PySide6.QtCore import QRect
from PySide6.QtWidgets import QPushButton, QWidget
from src.qt.flowlayout import FlowLayout
from tagstudio.qt.flowlayout import FlowLayout
def test_flow_layout_happy_path(qtbot):

View File

@@ -1,4 +1,4 @@
from src.qt.modals.folders_to_tags import generate_preview_data
from tagstudio.qt.modals.folders_to_tags import generate_preview_data
def test_generate_preview_data(library, snapshot):

View File

@@ -1,6 +1,7 @@
import pytest
from src.core.library import ItemType
from src.qt.widgets.item_thumb import BadgeType, ItemThumb
from tagstudio.core.library.alchemy.enums import ItemType
from tagstudio.qt.widgets.item_thumb import BadgeType, ItemThumb
@pytest.mark.parametrize("new_value", (True, False))

View File

@@ -1,4 +1,4 @@
from src.qt.widgets.preview_panel import PreviewPanel
from tagstudio.qt.widgets.preview_panel import PreviewPanel
def test_update_selection_empty(qt_driver, library):

View File

@@ -1,6 +1,6 @@
from src.core.library.alchemy.enums import FilterState
from src.core.library.json.library import ItemType
from src.qt.widgets.item_thumb import ItemThumb
from tagstudio.core.library.alchemy.enums import FilterState
from tagstudio.core.library.json.library import ItemType
from tagstudio.qt.widgets.item_thumb import ItemThumb
# def test_update_thumbs(qt_driver):
# qt_driver.frame_content = [

View File

@@ -1,5 +1,5 @@
from src.core.library import Tag
from src.qt.modals.build_tag import BuildTagPanel
from tagstudio.core.library.alchemy.models import Tag
from tagstudio.qt.modals.build_tag import BuildTagPanel
def test_tag_panel(qtbot, library):

View File

@@ -1,4 +1,4 @@
from src.qt.modals.tag_search import TagSearchPanel
from tagstudio.qt.modals.tag_search import TagSearchPanel
def test_update_tags(qtbot, library):

View File

@@ -8,9 +8,10 @@ from pathlib import Path
import pytest
from PIL import Image
from src.qt.widgets.thumb_renderer import ThumbRenderer
from syrupy.extensions.image import PNGImageSnapshotExtension
from tagstudio.qt.widgets.thumb_renderer import ThumbRenderer
@pytest.mark.parametrize(
["fixture_file", "thumbnailer"],

View File

@@ -2,12 +2,14 @@
# Licensed under the GPL-3.0 License.
# Created for TagStudio: https://github.com/CyanVoxel/TagStudio
import shutil
from pathlib import Path
import pytest
from src.core.constants import TS_FOLDER_NAME
from src.core.library.alchemy.library import Library
from tagstudio.core.constants import TS_FOLDER_NAME
from tagstudio.core.library.alchemy.library import Library
CWD = Path(__file__)
FIXTURES = "fixtures"

View File

@@ -3,10 +3,11 @@ from pathlib import Path
from tempfile import TemporaryDirectory
from PySide6.QtCore import QSettings
from src.core.constants import TS_FOLDER_NAME
from src.core.driver import DriverMixin
from src.core.enums import SettingItems
from src.core.library.alchemy.library import LibraryStatus
from tagstudio.core.constants import TS_FOLDER_NAME
from tagstudio.core.driver import DriverMixin
from tagstudio.core.enums import SettingItems
from tagstudio.core.library.alchemy.library import LibraryStatus
class TestDriver(DriverMixin):

View File

@@ -2,11 +2,12 @@
# Licensed under the GPL-3.0 License.
# Created for TagStudio: https://github.com/CyanVoxel/TagStudio
from pathlib import Path
from time import time
from src.core.enums import LibraryPrefs
from src.qt.widgets.migration_modal import JsonMigrationModal
from tagstudio.core.enums import LibraryPrefs
from tagstudio.qt.widgets.migration_modal import JsonMigrationModal
CWD = Path(__file__)

View File

@@ -2,11 +2,12 @@ from pathlib import Path
from tempfile import TemporaryDirectory
import pytest
from src.core.enums import DefaultEnum, LibraryPrefs
from src.core.library.alchemy import Entry, Library
from src.core.library.alchemy.enums import FilterState
from src.core.library.alchemy.fields import TextField, _FieldID
from src.core.library.alchemy.models import Tag
from tagstudio.core.enums import DefaultEnum, LibraryPrefs
from tagstudio.core.library.alchemy.enums import FilterState
from tagstudio.core.library.alchemy.fields import TextField, _FieldID
from tagstudio.core.library.alchemy.library import Library
from tagstudio.core.library.alchemy.models import Entry, Tag
def test_library_add_alias(library, generate_tag):

View File

@@ -1,7 +1,8 @@
import pytest
from src.core.library.alchemy.enums import FilterState
from src.core.library.alchemy.library import Library
from src.core.query_lang.util import ParsingError
from tagstudio.core.library.alchemy.enums import FilterState
from tagstudio.core.library.alchemy.library import Library
from tagstudio.core.query_lang.util import ParsingError
def verify_count(lib: Library, query: str, count: int):

View File

@@ -5,7 +5,7 @@ import pytest
import ujson as json
CWD = Path(__file__).parent
TRANSLATION_DIR = CWD / ".." / "resources" / "translations"
TRANSLATION_DIR = CWD / ".." / "src" / "tagstudio" / "resources" / "translations"
def load_translation(filename: str) -> dict[str, str]:
@@ -17,6 +17,10 @@ def get_translation_filenames() -> list[tuple[str]]:
return [(a.name,) for a in TRANSLATION_DIR.glob("*.json")]
def test_translation_dir():
assert TRANSLATION_DIR.exists()
def find_format_keys(format_string: str) -> set[str]:
formatter = string.Formatter()
return set([field[1] for field in formatter.parse(format_string) if field[1] is not None])
@@ -31,20 +35,18 @@ def test_format_key_validity(translation_filename: str):
continue
default_keys = find_format_keys(default_translation[key])
translation_keys = find_format_keys(translation[key])
assert default_keys.issuperset(
translation_keys
), f"Translation {translation_filename} for key {key} is using an invalid format key ({translation_keys.difference(default_keys)})" # noqa: E501
assert translation_keys.issuperset(
default_keys
), f"Translation {translation_filename} for key {key} is missing format keys ({default_keys.difference(translation_keys)})" # noqa: E501
assert default_keys.issuperset(translation_keys), (
f"Translation {translation_filename} for key {key} is using an invalid format key ({translation_keys.difference(default_keys)})" # noqa: E501
)
assert translation_keys.issuperset(default_keys), (
f"Translation {translation_filename} for key {key} is missing format keys ({default_keys.difference(translation_keys)})" # noqa: E501
)
@pytest.mark.parametrize(["translation_filename"], get_translation_filenames())
def test_for_unnecessary_translations(translation_filename: str):
default_translation = load_translation("en.json")
translation = load_translation(translation_filename)
assert set(
default_translation.keys()
).issuperset(
translation.keys()
), f"Translation {translation_filename} has unnecessary keys ({set(translation.keys()).difference(default_translation.keys())})" # noqa: E501
assert set(default_translation.keys()).issuperset(translation.keys()), (
f"Translation {translation_filename} has unnecessary keys ({set(translation.keys()).difference(default_translation.keys())})" # noqa: E501
)