From 3d866c55587ef8d407ba94cbd8209146da092555 Mon Sep 17 00:00:00 2001 From: Bob Bobs Date: Mon, 11 Aug 2025 20:06:21 -0700 Subject: [PATCH 1/2] feat: add random sorting --- src/tagstudio/core/library/alchemy/enums.py | 8 +++++++- src/tagstudio/core/library/alchemy/library.py | 2 ++ src/tagstudio/resources/translations/en.json | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/tagstudio/core/library/alchemy/enums.py b/src/tagstudio/core/library/alchemy/enums.py index f1d3106c3..4d1fb9f93 100644 --- a/src/tagstudio/core/library/alchemy/enums.py +++ b/src/tagstudio/core/library/alchemy/enums.py @@ -1,4 +1,5 @@ import enum +import random from dataclasses import dataclass, replace from pathlib import Path @@ -69,6 +70,7 @@ class SortingModeEnum(enum.Enum): DATE_ADDED = "file.date_added" FILE_NAME = "generic.filename" PATH = "file.path" + RANDOM = "sorting.mode.random" @dataclass @@ -78,6 +80,7 @@ class BrowsingState: page_index: int = 0 sorting_mode: SortingModeEnum = SortingModeEnum.DATE_ADDED ascending: bool = True + random_seed: int = 0 query: str | None = None @@ -120,7 +123,10 @@ def with_page_index(self, index: int) -> "BrowsingState": return replace(self, page_index=index) def with_sorting_mode(self, mode: SortingModeEnum) -> "BrowsingState": - return replace(self, sorting_mode=mode) + seed = self.random_seed + if mode == SortingModeEnum.RANDOM: + seed = random.randrange(2**32) + return replace(self, sorting_mode=mode, random_seed=seed) def with_sorting_direction(self, ascending: bool) -> "BrowsingState": return replace(self, ascending=ascending) diff --git a/src/tagstudio/core/library/alchemy/library.py b/src/tagstudio/core/library/alchemy/library.py index fe5bc341e..95d72769f 100644 --- a/src/tagstudio/core/library/alchemy/library.py +++ b/src/tagstudio/core/library/alchemy/library.py @@ -913,6 +913,8 @@ def search_library( sort_on = func.lower(Entry.filename) case SortingModeEnum.PATH: sort_on = func.lower(Entry.path) + case SortingModeEnum.RANDOM: + sort_on = func.sin(Entry.id + search.random_seed) statement = statement.order_by(asc(sort_on) if search.ascending else desc(sort_on)) if page_size is not None: diff --git a/src/tagstudio/resources/translations/en.json b/src/tagstudio/resources/translations/en.json index 6f29bd9f2..26af8987b 100644 --- a/src/tagstudio/resources/translations/en.json +++ b/src/tagstudio/resources/translations/en.json @@ -262,6 +262,7 @@ "settings.title": "Settings", "sorting.direction.ascending": "Ascending", "sorting.direction.descending": "Descending", + "sorting.mode.random": "Random", "splash.opening_library": "Opening Library \"{library_path}\"...", "status.deleted_file_plural": "Deleted {count} files!", "status.deleted_file_singular": "Deleted 1 file!", From aa219018f2db434ef6e32ece976a9b551234cfba Mon Sep 17 00:00:00 2001 From: Bob Bobs Date: Fri, 15 Aug 2025 17:09:29 -0700 Subject: [PATCH 2/2] fix: improve randomness of random sort --- src/tagstudio/core/library/alchemy/enums.py | 4 ++-- src/tagstudio/core/library/alchemy/library.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tagstudio/core/library/alchemy/enums.py b/src/tagstudio/core/library/alchemy/enums.py index 4d1fb9f93..09e679bd2 100644 --- a/src/tagstudio/core/library/alchemy/enums.py +++ b/src/tagstudio/core/library/alchemy/enums.py @@ -80,7 +80,7 @@ class BrowsingState: page_index: int = 0 sorting_mode: SortingModeEnum = SortingModeEnum.DATE_ADDED ascending: bool = True - random_seed: int = 0 + random_seed: float = 0 query: str | None = None @@ -125,7 +125,7 @@ def with_page_index(self, index: int) -> "BrowsingState": def with_sorting_mode(self, mode: SortingModeEnum) -> "BrowsingState": seed = self.random_seed if mode == SortingModeEnum.RANDOM: - seed = random.randrange(2**32) + seed = random.random() return replace(self, sorting_mode=mode, random_seed=seed) def with_sorting_direction(self, ascending: bool) -> "BrowsingState": diff --git a/src/tagstudio/core/library/alchemy/library.py b/src/tagstudio/core/library/alchemy/library.py index 95d72769f..b0d0a8cf5 100644 --- a/src/tagstudio/core/library/alchemy/library.py +++ b/src/tagstudio/core/library/alchemy/library.py @@ -914,7 +914,7 @@ def search_library( case SortingModeEnum.PATH: sort_on = func.lower(Entry.path) case SortingModeEnum.RANDOM: - sort_on = func.sin(Entry.id + search.random_seed) + sort_on = func.sin(Entry.id * search.random_seed) statement = statement.order_by(asc(sort_on) if search.ascending else desc(sort_on)) if page_size is not None: