Compare commits

..

296 Commits

Author SHA1 Message Date
Travis Abendshien
981cc60135 chore: bump version to v9.5.1 2025-03-06 16:32:19 -08:00
Travis Abendshien
2073a284fe fix: separate about screen title from translations (#836)
* fix: separate about screen title from translations

* chore: format with ruff's evil twin
2025-03-06 16:22:54 -08:00
Jann Stute
6d1ff90355 test: add tests for translations (#833)
* refactor: simplify pathlib imports

* feat: add tests for invalid format keys and missing / unnecessary translations

* feat: parametrise format key test

* feat: parametrise completeness test

* fix: include more useful information in the error message

* refactor: remove unused method

* refactor: extract translation loading to a separate function

* fix: include more useful information in the error message

* fix: don't fail test when language hasn't been completely translated
2025-03-06 15:28:48 -08:00
Weblate (bot)
4fe76f13fd fix(translations): fix invalid placeholders (#835)
* Translated using Weblate (Turkish)

Currently translated at 24.9% (72 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tr/
Translation: TagStudio/Strings

* Translated using Weblate (Filipino)

Currently translated at 44.6% (129 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fil/
Translation: TagStudio/Strings

* Translated using Weblate (Tamil)

Currently translated at 24.9% (72 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/
Translation: TagStudio/Strings

* Translated using Weblate (Danish)

Currently translated at 3.8% (11 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/da/
Translation: TagStudio/Strings

* Translated using Weblate (Spanish)

Currently translated at 96.1% (278 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/
Translation: TagStudio/Strings

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 17.9% (52 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/nb_NO/
Translation: TagStudio/Strings

* Translated using Weblate (Toki Pona)

Currently translated at 36.3% (105 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tok/
Translation: TagStudio/Strings

---------

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
2025-03-06 15:22:57 -08:00
Weblate (bot)
6690f5bc09 translations: update Portuguese(BR), German, Russian, Spanish, French; fix formatting keys (#826)
* Translated using Weblate (Turkish)

Currently translated at 22.4% (65 of 289 strings)

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tr/
Translation: TagStudio/Strings

* Translated using Weblate (Filipino)

Currently translated at 43.9% (127 of 289 strings)

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fil/
Translation: TagStudio/Strings

* Translated using Weblate (Tamil)

Currently translated at 22.4% (65 of 289 strings)

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/
Translation: TagStudio/Strings

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 88.9% (257 of 289 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 88.9% (257 of 289 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 64.7% (187 of 289 strings)

Co-authored-by: Helder Lima <vinicius-helder@hotmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/
Translation: TagStudio/Strings

* Translated using Weblate (German)

Currently translated at 98.9% (286 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Theasacraft <spam@accounts.samuelbellmann.de>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/
Translation: TagStudio/Strings

* Translated using Weblate (Danish)

Currently translated at 3.8% (11 of 289 strings)

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/da/
Translation: TagStudio/Strings

* Translated using Weblate (Russian)

Currently translated at 73.3% (212 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: werdei <6pe3ep1lu@mozmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ru/
Translation: TagStudio/Strings

* Translated using Weblate (Polish)

Currently translated at 97.5% (282 of 289 strings)

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pl/
Translation: TagStudio/Strings

* Translated using Weblate (Spanish)

Currently translated at 95.8% (277 of 289 strings)

Translated using Weblate (Spanish)

Currently translated at 95.8% (277 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Joan <joancanalscrehuet@gmail.com>
Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/
Translation: TagStudio/Strings

* Translated using Weblate (French)

Currently translated at 100.0% (289 of 289 strings)

Translated using Weblate (French)

Currently translated at 100.0% (289 of 289 strings)

Translated using Weblate (French)

Currently translated at 100.0% (289 of 289 strings)

Translated using Weblate (French)

Currently translated at 100.0% (289 of 289 strings)

Co-authored-by: Aless <dev@aless.ch>
Co-authored-by: Bamowen <mathieu.monsauret@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Med <45147847+kitsumed@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/
Translation: TagStudio/Strings

* Translated using Weblate (Swedish)

Currently translated at 25.2% (73 of 289 strings)

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/sv/
Translation: TagStudio/Strings

* Translated using Weblate (Chinese (Traditional Han script))

Currently translated at 68.8% (199 of 289 strings)

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/zh_Hant/
Translation: TagStudio/Strings

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 16.9% (49 of 289 strings)

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/nb_NO/
Translation: TagStudio/Strings

* Translated using Weblate (Toki Pona)

Currently translated at 33.2% (96 of 289 strings)

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tok/
Translation: TagStudio/Strings

---------

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Co-authored-by: Helder Lima <vinicius-helder@hotmail.com>
Co-authored-by: Theasacraft <spam@accounts.samuelbellmann.de>
Co-authored-by: werdei <6pe3ep1lu@mozmail.com>
Co-authored-by: Joan <joancanalscrehuet@gmail.com>
Co-authored-by: Aless <dev@aless.ch>
Co-authored-by: Bamowen <mathieu.monsauret@gmail.com>
Co-authored-by: Med <45147847+kitsumed@users.noreply.github.com>
2025-03-06 14:02:21 -08:00
Travis Abendshien
7e75087b24 fix: restore translate_formatted() method as format() (#830)
* fix: restore `translate_formatted()` method

* fix: set "Create & Add" button text

* refactor: rename "translate_formatted" to "format"

* translations: replace invalid format key names with "{unknown_key}"
2025-03-06 13:05:56 -08:00
Paula Rumeu
07b7d40926 docs: fix category typo (#834) 2025-03-06 03:54:44 -08:00
Travis Abendshien
80aab1ec96 chore: tweak pull request template 2025-03-04 14:27:40 -08:00
Travis Abendshien
bcf3b2f96b fix: prevent future library versions from being opened 2025-03-03 15:02:35 -08:00
Travis Abendshien
d94befed5d Merge branch 'main' of https://github.com/TagStudioDev/TagStudio 2025-03-03 14:18:25 -08:00
Travis Abendshien
d91ee5dbf7 chore: bump version to v9.5.0 2025-03-03 14:16:44 -08:00
Travis Abendshien
ea8d074c51 chore: remove leftover log statement 2025-03-03 14:16:34 -08:00
Travis Abendshien
186c6e2139 ui: change default tag color to white 2025-03-03 14:15:10 -08:00
Xarvex
c695f1765f chore(ci): add PR template (#824) 2025-03-03 14:14:46 -06:00
Travis Abendshien
077f91af88 ui: don't show the deprecated "Autofill" macro 2025-03-03 11:39:32 -08:00
Travis Abendshien
accf50ccf9 ui: change default sorting direction to descending 2025-03-03 11:32:41 -08:00
Travis Abendshien
9f9a5ccf44 fix: catch OverflowError when displaying video duration 2025-03-03 11:26:07 -08:00
Weblate (bot)
ee23ef3451 translations: update Filipino, Portuguese(BR), German, Hungarian, Polish, Spanish, French (#809)
* Translated using Weblate (Filipino)

Currently translated at 43.9% (127 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: searinminecraft <114207889+searinminecraft@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fil/
Translation: TagStudio/Strings

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 64.7% (187 of 289 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 63.3% (183 of 289 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 49.4% (143 of 289 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 49.4% (143 of 289 strings)

Co-authored-by: Alexander Lennart Formiga Johnsson <alexander_formiga@hotmail.com>
Co-authored-by: DaviMarquezeli <Davi.Marquezeli@gmail.com>
Co-authored-by: Helder Lima <vinicius-helder@hotmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/
Translation: TagStudio/Strings

* Translated using Weblate (German)

Currently translated at 98.9% (286 of 289 strings)

Translated using Weblate (German)

Currently translated at 98.9% (286 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: JoeJoeTV <hannes1033@gmail.com>
Co-authored-by: Kurt S <mail@kurtys.de>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/
Translation: TagStudio/Strings

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (289 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/
Translation: TagStudio/Strings

* Translated using Weblate (Polish)

Currently translated at 97.5% (282 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: qronikarz <qronikarz@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pl/
Translation: TagStudio/Strings

* Translated using Weblate (Spanish)

Currently translated at 57.7% (167 of 289 strings)

Translated using Weblate (Spanish)

Currently translated at 55.0% (159 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Nginearing <142851004+Nginearing@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/
Translation: TagStudio/Strings

* Translated using Weblate (French)

Currently translated at 100.0% (289 of 289 strings)

Translated using Weblate (French)

Currently translated at 100.0% (289 of 289 strings)

Translated using Weblate (French)

Currently translated at 100.0% (289 of 289 strings)

Translated using Weblate (French)

Currently translated at 100.0% (289 of 289 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Med <45147847+kitsumed@users.noreply.github.com>
Co-authored-by: Obscaeris <translation@obscaeris.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/
Translation: TagStudio/Strings

---------

Co-authored-by: searinminecraft <114207889+searinminecraft@users.noreply.github.com>
Co-authored-by: Alexander Lennart Formiga Johnsson <alexander_formiga@hotmail.com>
Co-authored-by: DaviMarquezeli <Davi.Marquezeli@gmail.com>
Co-authored-by: Helder Lima <vinicius-helder@hotmail.com>
Co-authored-by: JoeJoeTV <hannes1033@gmail.com>
Co-authored-by: Kurt S <mail@kurtys.de>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Co-authored-by: qronikarz <qronikarz@users.noreply.hosted.weblate.org>
Co-authored-by: Nginearing <142851004+Nginearing@users.noreply.github.com>
Co-authored-by: Med <45147847+kitsumed@users.noreply.github.com>
Co-authored-by: Obscaeris <translation@obscaeris.com>
2025-03-03 11:17:33 -08:00
Jann Stute
2a787592b6 fix: resouce leak in translate_with_setter by deleting the offending code (#817)
* feat: implement first class for translated widget

* feat: add further translated widget types

* refactor: replace usages of translate_qobject with appropriate classes

* refactor: remove wrapper classes

* refactor: remove unnecessary used of Translations.formatted

* refactor: remove further unnecessary format calls

* refactor: replace calls for Translations.formatted with calls to str.format and remove some unused code

* refactor: remove TranslatedString class

* refactor: replace translate_with_setter with direct calls to the setter
2025-03-03 11:13:49 -08:00
Travis Abendshien
152c2b20ba docs: add "sort by filename" to roadmap 2025-03-02 22:13:00 -08:00
Travis Abendshien
1b5b40792c Create FUNDING.yml 2025-03-02 21:58:42 -08:00
SkeleyM
4b381e78ba docs: fix slight spelling error (#820) 2025-02-27 14:23:05 -08:00
Travis Abendshien
b1126d5313 fix: open libraries from v9.5.0-pr1 in newer versions (#815)
* ui: show more informative library error messages

* tests: add sqlite db migration tests

* tests: fix and refactor migration tests

* fix: apply db8 schema changes before repairing db6

* docs: add save file format change log

* chore: remove db version explanations from docstrings
2025-02-24 15:14:54 -08:00
Travis Abendshien
f9ca743b64 docs: add custom color info 2025-02-20 15:14:51 -08:00
Travis Abendshien
04bd1bc027 fix(docs): restore broken links, ignore callout formatting 2025-02-20 14:24:12 -08:00
Haider Ali
ecc0bb57fb docs: change "Tag Manager" to "Manage Tags" (#806) 2025-02-17 20:42:48 -08:00
Travis Abendshien
d11b514bab fix: use remove() instead of difference() for self collision checks 2025-02-17 15:39:43 -08:00
Travis Abendshien
fe94d84b94 ci: ignore specific pyright flags 2025-02-17 14:52:59 -08:00
Travis Abendshien
db408f09c4 chore: bump version to v9.5.0-pr4 2025-02-17 14:47:22 -08:00
Travis Abendshien
61b9fcf764 feat(ui): add language setting (#803)
* feat(ui): add language setting

* translations: implement remaining todos

* ui: show language names in settings instead of codes

* translations: add Dutch setting, anticipating #798
2025-02-17 14:45:30 -08:00
Travis Abendshien
28de21ade7 feat(ui)!: user-created tag colors (#801)
* feat: custom tag colors

* ui: minor ui polish

* ui: add confirmation for deleting colors

* ui: match tag_color_preview focused style

* ui: reduce spacing between color swatch groups

* ui!: change default behavior of secondary color

The secondary color now acts as only the text color by default, with the new `color_border` bool serving to optionally restore the previous text + colored border behavior.

* ui: adjust focused tag/color button styles

* fix: avoid namespace collision

* fix: make reserved namespace check case-insensitive

* ui: add namespace description + prompt

* fix: don't reset tag color if none are chosen

* refactor(ui): use form layout for build_color

* fix(ui): dynamically scale field title widget

* feat(ui): add additional tag shade colors

Add "burgundy", "dark-teal", and "dark_lavender" tag colors.

* fix: don't check for self in collision checks

* fix: update tag references on color update

* fix(ui): stop fields widgets expanding indefinitely
2025-02-17 14:36:34 -08:00
Weblate (bot)
2173d1d4f4 translations: add Dutch; update Hungarian, Spanish, French (#798)
* Translated using Weblate (Hungarian)

Currently translated at 100.0% (259 of 259 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/
Translation: TagStudio/Strings

* Translated using Weblate (Dutch)

Currently translated at 40.1% (104 of 259 strings)

Added translation using Weblate (Dutch)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Pheubel <luca.guagliardo@live.nl>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/nl/
Translation: TagStudio/Strings

* Translated using Weblate (Spanish)

Currently translated at 51.7% (134 of 259 strings)

Translated using Weblate (Spanish)

Currently translated at 51.3% (133 of 259 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Nginearing <142851004+Nginearing@users.noreply.github.com>
Co-authored-by: noceno <pasitobajet@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/
Translation: TagStudio/Strings

* Translated using Weblate (French)

Currently translated at 100.0% (259 of 259 strings)

Translated using Weblate (French)

Currently translated at 100.0% (259 of 259 strings)

Translated using Weblate (French)

Currently translated at 100.0% (259 of 259 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Med <45147847+kitsumed@users.noreply.github.com>
Co-authored-by: Obscaeris <translation@obscaeris.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/
Translation: TagStudio/Strings

---------

Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Co-authored-by: Pheubel <luca.guagliardo@live.nl>
Co-authored-by: Nginearing <142851004+Nginearing@users.noreply.github.com>
Co-authored-by: noceno <pasitobajet@gmail.com>
Co-authored-by: Med <45147847+kitsumed@users.noreply.github.com>
Co-authored-by: Obscaeris <translation@obscaeris.com>
2025-02-17 14:33:21 -08:00
SkeleyM
c1ec8a6650 feat(ui): clickable links in about section (#799) 2025-02-14 09:32:00 -08:00
Travis Abendshien
69d3a6ed09 docs: update library search 2025-02-14 09:25:57 -08:00
Travis Abendshien
e481ab64c9 docs: consolidate feature roadmap 2025-02-14 08:42:44 -08:00
Travis Abendshien
986ccabc81 chore: bump version to v9.5.0-pr3 2025-02-10 11:22:00 -08:00
Travis Abendshien
297fdf22e8 feat: add smartcase and globless path searches (#743)
* fix: return path_strings in session

* feat: add smartcase and globless path search

Known issues: failing tests, sluggish autocomplete

* fix: all operational searches

* fix: limit path autocomplete to 100 items

* tests: add test cases
2025-02-10 10:26:02 -08:00
Weblate (bot)
319ef9a5fe translations: update Danish, Hungarian (#785)
* Translated using Weblate (Danish)

Currently translated at 4.6% (11 of 237 strings)

Co-authored-by: Jumle <juliusv135@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/da/
Translation: TagStudio/Strings

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (237 of 237 strings)

Translated using Weblate (Hungarian)

Currently translated at 100.0% (236 of 236 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/
Translation: TagStudio/Strings

---------

Co-authored-by: Jumle <juliusv135@gmail.com>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
2025-02-10 10:23:58 -08:00
Travis Abendshien
6b646f8955 perf: optimize query methods and reduce preview panel updates (#794)
* fix(ui): don't update preview for non-selected badge toggles

* ui: optimize badge updating

NOTE: In theory this approach opens the doors for a visual state mismatch between the tags shown and the tags on the actual entry. The performance increase comes from the fact that `get_entry_full()` isn't called, which is the real bottleneck here.

* perf: optimize query methods
2025-02-09 18:33:47 -08:00
Travis Abendshien
a2b9237be4 fix(ui): expand usage of esc for closing modals (#793)
* fix(ui): expand usage of esc for closing modals

* chore: remove log statements

* refactor: use Qt enum in place of magic number

* ui: use enter key to save panel widgets
2025-02-09 18:33:29 -08:00
ChloeVZ
abc7cc3915 docs: improve python and venv setup instructions in CONTRIBUTING.md (#791)
* docs: refer to pyenv in CONTRIBUTING.md

This commit was made in order to account for users who may already have
a Python installation that isn't 3.12.

A good real world scenario where this may be a problem is users running
on rolling release Linux distributions, such as Arch Linux which
provides bleeding edge updates in a weekly basis.

Continuing with Arch Linux as an example, it provides Python 3.13, which
the current version of TagStudio doesn't seem to work with, an issue I
encountered myself this morning.

In some systems like Windows, this may not matter, but it is an issue
nonetheless, and users using a package manager centric system can't be
expected to downgrade/upgrade their Python version for TagStudio, as
this may cause issues in their system.

The easiest way to solve this is with pyenv, which enables users to
install other Python versions independent from each other, aside from
the system install, and allows specifying a version to use for a
directory (And its subdirectories), the current terminal session, or the
entire system if desired.

Here is a short, technical and objective summary of the changes:
- Updated `.gitignore` to to ignore `.python-version` which pyenv uses.
- Updated CONTRIBUTING.md to refer to pyenv for versioning issues.
    - pyenv is listed as a prerequisite, specifying in parenthesis that it's only for when your Python install isn't 3.12.
    - The "Creating a Python Virtual Environment" section now has an additional step at the beginning, to check that the current Python installation is 3.12.
        - As part of this added step, there are steps to use pyenv to install Python 3.12 separately from the existing Python installation, and activate it for the TagStudio root folder, in case it's not the appropriate version.
    - The numbering of the other steps was offset accordingly.
    - The "Manually Launching (Outside of an IDE)" section now refers to the above first step, should the user encounter some kind of error.

* docs: refer to alternate shells in CONTRIBUTING.md

Some users may not be using the default shell for their system, and
Linux users are the most likely to do this, though this can be seen in
macOS as well. People will often use shells like fish which is not POSIX
compliant but works very well and has great auto-completion, it's very
user friendly.

The reason why I care about this is that the instructions specify to use
.venv/bin/activate which is a bash script and will not run on fish or
csh, and if you take a look at the script, indeed it says it will only
run with bash.

Python will provide alternate scripts for other shells, and at least on
my system (CachyOS), those are scripts for Powershell, bash, fish and
csh. People using these alternate shells, who don't know this may be
confused when running the script referenced in CONTRIBUTING.md and
seeing it fail completely.

The only real change in this commit was adding under the "Linux/macOS"
command in step 3 (step 2 prior to my last commit) of the "Creating a
Python Virtual Environment" section, a short instruction to switch to
the default shell, or use the appropriate script for the user's
preferred shell if any (Since, at least on my system, there aren't
scripts for every shell, for example there is no activate.zsh file).

* fix: modal windows now have the Qt.Dialog flag

Set the Qt.Dialog flag for modal windows, such as "Add Field" so that
they will be seen as dialogs in the backend. This change is unlikely to
be at all noticeable in systems like Windows, but for users running
tiling window managers like bspwm or Sway, this will prevent these modal
windows from being tiled alongside the main window, instead they will be
floating on top, which is the expected behaviour seen on floating window
managers, like the ones used by Windows and macOS.

Added self.setWindowFlag(Qt.Dialog, on=True) # type: ignore to the
following files:
- tagstudio/src/qt/modals/add_field.py
- tagstudio/src/qt/modals/delete_unlinked.py
- tagstudio/src/qt/modals/drop_import.py
- tagstudio/src/qt/modals/file_extension.py
- tagstudio/src/qt/modals/fix_dupes.py
- tagstudio/src/qt/modals/fix_unlinked.py
- tagstudio/src/qt/modals/folders_to_tags.py
- tagstudio/src/qt/modals/mirror_entities.py
- tagstudio/src/qt/widgets/paged_panel/paged_panel.py
- tagstudio/src/qt/widgets/panel.py
- tagstudio/src/qt/widgets/progress.py

Note that without adding # type: ignore, MyPy *will* give out an error,
presumably because PySide6 is missing type hints for several things, and
this may *or* may not be a justifiable use of # type: ignore, which
throws the MyPy type checking for that line out the window.

Ref: #392, #464

* fix: I forgot to run ruff format

* revert: changes to docs and gitignore

This revert is for moving the referenced changes to their own pull request.

Refs: 15f4f38, a25ef8c

* docs: other shells and pyenv in CONTRIBUTING.md

This commit changes CONTRIBUTING.md to refer to pyenv in the case of
issues with Python versions, as well as downloading the correct version
off of the Python website alternatively. It also now elaborates on the
process of running the Python virtual environment on Linux and macOS, by
referencing activation scripts for alternative shells such as fish and
CSH.

The table added to CONTRIBUTING.md is taken from the official Python
documentation: https://docs.python.org/3.12/library/venv.html

* revert: accidental inclution of #464

Refs: a51550f, 5854ccc
2025-02-06 21:41:01 -08:00
Travis Abendshien
a3df70bb8d feat: port file trashing (#409) to v9.5 (#792)
* feat: port file trashing (#409) to sql

* translations: translate file deletion actions

* fix: rename method from refactor conflict

* refactor: implement feedback
2025-02-05 19:25:10 -08:00
Travis Abendshien
466af1e6a6 refactor(ui): recycle tag list in TagSearchPanel (#788)
* feat(ui): recycle tag list in `TagSearchPanel`

* chore: address mypy warnings

* fix: order results from sql before limiting

* fix(ui): check for self.exclude before remaking sets

* fix(ui): only init tag manager and file ext manager once

* fix(ui:): remove redundant tag search panel updates

* update code comments and docstrings

* feat(ui): add tag view limit dropdown

* ensure disconnection of file_extension_panel.saved
2025-02-05 19:15:28 -08:00
Travis Abendshien
26d3b1908b fix(ui): hide library actions when no library is open (#787) 2025-02-04 13:53:03 -08:00
Travis Abendshien
f38a79b06e chore: bump version to v9.5.0-pr2 2025-02-03 16:22:02 -08:00
Travis Abendshien
dbf7353bdf fix(ui): improve tagging ux (#784)
* fix(ui): always reset tag search panel when opened

* feat: return parent tags in tag search

Known issue: this bypasses the tag_limit

* refactor: use consistant `datetime` imports

* refactor: sort by base tag name to improve performance

* fix: escape `&` when displaying tag names

* ui: show "create and add" tag with other results

* fix: optimize and fix tag result sorting

* feat(ui): allow tags in list to be selected and added by keyboard

* ui: use `esc` to reset search focus and/or close modal

* fix(ui): add pressed+focus styling to "create tag" button

* ui: use `esc` key to close `PanelWidget`

* ui: move disambiguation button to right side

* ui: expand clickable area of "-" tag button, improve styling

* ui: add "Ctrl+M" shortcut to open tag manager

* fix(ui): show "add tags" window title when accessing from home
2025-02-03 16:15:40 -08:00
Travis Abendshien
480328b83b fix: patch incorrect description type & invalid disambiguation_id refs (#782)
* fix: update DESCRIPTION to the TEXT_BOX type

* fix: remove `disambiguation_id` refs with a tag is deleted
2025-02-03 15:32:11 -08:00
Travis Abendshien
6a54323307 refactor: wrap migration_iterator lambda in a try/except block (#773) 2025-02-03 15:31:43 -08:00
Travis Abendshien
f48b363383 fix: catch ParsingError (#779)
* fix: move `path_strings` var inside `with` block

* refactor: move lambda to local function

* fix: catch `ParsingError` and return no results

* refactor: move `ParsingError` handling out to `QtDriver`

Reverts changes made to `test_search.py` and `enums.py`.
2025-02-03 15:31:12 -08:00
Travis Abendshien
634e1c7fe9 chore: update pyproject.toml 2025-02-02 23:29:53 -08:00
Travis Abendshien
90a826d128 fix(ui): reduce field title width to make room for edit and delete buttons 2025-02-02 17:13:08 -08:00
SkeleyM
93fc28e092 fix: allow tag names with colons in search (#765)
* Refactor allowing colons

* fix formatting
2025-02-02 15:56:50 -08:00
SkeleyM
80c7e81e69 fix: save all tag attributes from "Create & Add" modal (#762) 2025-02-02 13:49:17 -08:00
SkeleyM
f212e2393a fix(docs): fix screenshot sometimes not rendering (#775)
* Fix image not showing up

* formatting
2025-02-02 13:44:34 -08:00
Travis Abendshien
d7958892b7 docs: add more links to index.md 2025-02-01 14:09:17 -08:00
Travis Abendshien
5be7dfc314 docs: add library_search page 2025-02-01 14:06:41 -08:00
Travis Abendshien
6e402ac34d docs: add note about glob searching in the readme 2025-01-31 23:45:31 -08:00
Travis Abendshien
9bdbafa40c docs: add information about "tag manager" 2025-01-31 23:42:37 -08:00
Travis Abendshien
2215403201 fix: don't wrap field names too early 2025-01-31 23:40:47 -08:00
pinhead
16ebd89196 docs: fix typo for "category" in usage.md (#760) 2025-01-31 21:46:30 -08:00
Travis Abendshien
f5ff4d78c1 docs: update field and library pages 2025-01-31 17:23:33 -08:00
Travis Abendshien
df04d49770 translations: fix typo in json_migration.info.description 2025-01-31 16:39:27 -08:00
Travis Abendshien
a2f9685bc0 fix: catch ImportError for pillow_jxl module 2025-01-31 16:30:06 -08:00
Travis Abendshien
880c8ef45f chore: bump version to v9.5.0 Pre-Release 1; update docs (#751)
* chore: change version branch to "Pre-Release 1"

* docs: update docstring for JSON `open_library()`

Update method docstring with exact starting and ending versions now that they exist.

* docs: update README, CONTRIBUTING.md, & index.md

* docs: update roadmap

* docs: fix typo in README, change callout

* docs: update docs site with v9.5 features

* docs: remove warning from index.md
2025-01-31 15:43:47 -08:00
Travis Abendshien
1b3b32de22 ci: bump minimum macOS build target to 13 2025-01-31 15:40:53 -08:00
Weblate (bot)
787af60833 translations: update Czech, Hungarian, Polish, French (#746)
* Translated using Weblate (Czech)

Currently translated at 7.8% (18 of 228 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Jirka Čapek <jirkacapek13@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/cs/
Translation: TagStudio/Strings

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (234 of 234 strings)

Translated using Weblate (Hungarian)

Currently translated at 100.0% (231 of 231 strings)

Translated using Weblate (Hungarian)

Currently translated at 100.0% (228 of 228 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/
Translation: TagStudio/Strings

* Translated using Weblate (Polish)

Currently translated at 94.4% (221 of 234 strings)

Co-authored-by: qronikarz <qronikarz@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pl/
Translation: TagStudio/Strings

* Translated using Weblate (French)

Currently translated at 73.1% (169 of 231 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: aless <61836900+alessdangelo@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/
Translation: TagStudio/Strings

---------

Co-authored-by: Jirka Čapek <jirkacapek13@gmail.com>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Co-authored-by: qronikarz <qronikarz@users.noreply.hosted.weblate.org>
Co-authored-by: aless <61836900+alessdangelo@users.noreply.github.com>
2025-01-31 14:46:55 -08:00
mashed5894
225fe98c20 feat: port copy/paste fields and tags to sql (#722)
* implement copy/paste for fields and tags

* fix tests

* fixed badge refresh on pasting

* renamed translation field

* ignore duplicate tags on insert

* fixes

* break into several statements to satisfy tests

* chore: format with ruff
2025-01-31 14:38:01 -08:00
Travis Abendshien
496c87c7c3 ui: tweak build_tag and tag styles 2025-01-31 13:17:22 -08:00
Travis Abendshien
7c89975165 fix(ui): (mostly) fix right-click search option on tags (#756) 2025-01-30 23:32:14 -08:00
Travis Abendshien
ca7e84d1b4 fix(ui): use consistent dark mode colors for all systems (#752) 2025-01-30 22:10:06 -08:00
Travis Abendshien
e0d21c14a3 fix(ui): restore Windows accent color on PySide 6.8.0.1 (Fix #668) (#755)
* fix(ui): use the new correct(ish) accent color role for Windows

* ui: boost Windows `AlternateBase` lightness
2025-01-30 22:09:50 -08:00
Travis Abendshien
82edbee276 ui: shortcut to add tags to selected entries; change click behavior of tags to edit (#749)
* ui: change on_click behavior of tags to edit

* fix: pass library to tag_widget

* feat: add `add_tag_to_selected` shortcut

* fix: only enable `add_tag_to_selected` shortcut when usable
2025-01-29 21:28:08 -08:00
Travis Abendshien
d1b006a897 feat(ui): re-implement tag display names on sql (#747)
* feat: add disambiguation_tag column to tags table

* feat(ui): re-add tag display names

* fix(ui): allow empty disambiguation selection

* ui: restore basic tab functionality

* fix: don't set disambiguation_id for self-parented JSON tags

* fix: return consistent search results
2025-01-29 19:42:55 -08:00
Travis Abendshien
54b8397e92 fix: check for tag name partiy during JSON migration (#748)
* fix: apply JSON user edits to built-in tag names and shorthands

* fix: test for tag name parity when migrating from JSON
2025-01-29 19:42:41 -08:00
Travis Abendshien
607aafb4cd ci: lower test coverage threshold to 40% 2025-01-29 16:17:26 -08:00
Travis Abendshien
6ee5304b52 fix(ui): use camera white balance for raw images 2025-01-29 00:34:32 -08:00
Travis Abendshien
275cd1b20e fix(ui): revert all item_thumb "pressed" changes (#742) 2025-01-28 11:00:39 -08:00
Travis Abendshien
ba7e13041b feat: add date columns to the entries table (#740)
* feat: add date_created, date_modified, and date_added columns to entries table

* feat: start storing date_added dates
2025-01-28 01:57:01 -08:00
Travis Abendshien
1ba97d50c2 refactor: change exception log levels to error inside library.py 2025-01-28 01:19:30 -08:00
Travis Abendshien
20d788af29 fix: refactor and fix bugs with missing_files.py (#739)
* fix: relink unlinked entry to existing entry without sql error (#720)

* edited and added db functions get_entry_full_by_path & merge_entries

* implemented edge case for entry existing on relinking

* added test for merge_entries

* fix: don't remove item while iterating over list

* fix: catch `FileNotFoundError` for unlinked raw files

* refactor: rename methods and variables in missing_files.py

* refactor: rename `missing_files_count` to `missing_file_entries_count`

---------

Co-authored-by: mashed5894 <mashed5894@gmail.com>
2025-01-27 23:49:39 -08:00
Travis Abendshien
458925fbf7 translations: fix typo in drop import 2025-01-27 12:08:16 -08:00
Travis Abendshien
f96ea6b546 fix: always catch db mismatch (#738)
* fix: always catch db mismatch

* chore: remove/modify log statements

* translations: translate library version mismatch

* style: fix line over col limit
2025-01-27 11:48:57 -08:00
Weblate (bot)
19cdd1bf92 translations: update Czech, Hungarian (#727)
* Translated using Weblate (Czech)

Currently translated at 1.7% (4 of 224 strings)

Added translation using Weblate (Czech)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Jirka Čapek <jirkacapek13@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/cs/
Translation: TagStudio/Strings

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (224 of 224 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/
Translation: TagStudio/Strings

---------

Co-authored-by: Jirka Čapek <jirkacapek13@gmail.com>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
2025-01-27 11:48:28 -08:00
Travis Abendshien
2a97a5b3aa perf: add all new library entries at once (#737) 2025-01-27 11:43:04 -08:00
Travis Abendshien
14599e90a3 fix: keep initial id order in get_entries_full() (#736)
* fix: keep initial id order in `get_entries_full()`

* fix: correct variable names
2025-01-27 11:41:01 -08:00
Travis Abendshien
ee14e2c200 fix: search for tag aliases in tag search (#726) 2025-01-27 11:40:06 -08:00
Travis Abendshien
c06f3bb336 feat!: expanded tag color system (#709)
* attempt at adding `TagColor` table

* store both columns of `TagColor` inside `Tag` table

* fix: fix tag color relationships

* refactor: replace TagColor enums with TagColorGroup system

* ui: derive tag accent colors from primary

* refactor: move dynamic tag color logic, apply to "+" button

* feat(ui): add neon tag colors

* remove tag text color field

* ui: use secondary color for border and text

* ui: add TagColorPreview widget

* feat(ui): add new tag color selector

* ui: add color name tooltips

* ui: tweak tag colors and selector

* feat: add `namespaces` table

* translations: add + update translation keys

* tests: update fixtures

* chore: code cleanup

* ui: add spacing between color groups

* fix: expand refactor to create and add button

* chore: format with ruff
2025-01-27 11:39:42 -08:00
Travis Abendshien
4c337cb1a3 feat(ui): add thumbnail caching (#694)
* feat(ui): add thumbnail caching

* feat: enforce total size limit for thumb cache

* fix: add file modification date to thumb hash

This change allows for modified files to have their cached thumbnail regenerated.

* feat: add menu option to clear thumbnail cache

* fix: check if `cached_path` is None further on

* refactor: move configurable cache vars to class level

* docs: complete roadmap items

* feat: use cache size limit from config file

TODO: Store this on a per-library basis and allow it to be configurable inside the program.

* fix: move `last_cache_folder` to class level

* chore: add/tweak type hints

* refactor: use make `CacheManager` a singleton
2025-01-27 11:39:10 -08:00
Travis Abendshien
3606edf615 fix: have pydub use known ffmpeg+ffprobe locations (#724)
* fix: have pydub use known ffmpeg+ffprobe locations

* chore: format with ruff
2025-01-26 01:51:15 -08:00
Travis Abendshien
f2a2f9a36d fix: replace calls to translate_qobject with translate_formatted inside TagWidget (#735)
* fix: replace `translate_qobject` calls with `translate_formatted`

* refactor: misc code cleanup
2025-01-26 01:50:36 -08:00
SkeleyM
921a8875de fix(ui): don't always create tag on enter ( #731) 2025-01-24 17:03:39 -08:00
mashed5894
2a41c152b3 fix: restore environment before launching external programs (#707)
* rename promptless_Popen

* linux: restore env before calling popen

* windows: set dll directory to default before calling popen

* ruff formatting suggestions

* edited silent_popen docstring
2025-01-24 13:56:35 -08:00
SkeleyM
0ead238aac fix: restore opening last library on startup (#729) 2025-01-24 13:38:42 -08:00
Travis Abendshien
9116cdc9a5 docs: fix typo in readme 2025-01-23 20:15:54 -08:00
mashed5894
17c62802c0 fix: sort tag results (#721)
* sort search results

* ruff fix
2025-01-23 13:41:57 -08:00
Travis Abendshien
ac6774ed23 fix(ui): don't set frame when playing videos
Fixes some videos not being able to play. The frame setting step was copied from thumbnail rendering and shouldn't be used here regardless.
2025-01-23 00:22:03 -08:00
Travis Abendshien
eb1f634d38 fix: don't add ._ files to libraries 2025-01-23 00:19:35 -08:00
Travis Abendshien
a1ab335dcb translations: fix fr.json syntax error 2025-01-22 16:38:45 -08:00
SkeleyM
89a8abca75 feat(ui): add audio volume slider (#691)
* Add Volume Slider

* Slider reflects muted state

* Default Volume Value

* Update roadmap to reflect current state

* Forgot a period in a comment

* Add suggestions

* Update tagstudio/src/qt/widgets/media_player.py

Co-authored-by: VasigaranAndAngel <72515046+VasigaranAndAngel@users.noreply.github.com>

* remove unwanted line

---------

Co-authored-by: VasigaranAndAngel <72515046+VasigaranAndAngel@users.noreply.github.com>
2025-01-22 16:07:13 -08:00
Travis Abendshien
a02c43c115 feat(ui): add configurable splash screens (#703)
* refactor: move splash images to resource_manager

* feat(ui): add new splash screen widget

* style: restore old resource manager log style

* fix: scale font size for Segoe UI
2025-01-22 16:02:58 -08:00
Travis Abendshien
857f40f2e3 fix: preview panel + main window fixes and optimizations (#700)
* fix: only update file preview when necessary

* fix: don't update thumb from tag_box callbacks

* fix: reset preview panel and filters when loading new library

* fix: clear library state on close; close old library on open

* fix: reset scrollbar position on library close
2025-01-22 16:00:01 -08:00
Travis Abendshien
16fb0290a0 fix: don't add default title field, use proper phrasing for adding files (#701)
* fix: use correct message when adding macros

* fix: no longer add title field to new entries

* fix: use `entries` dialog title instead of `macros`
2025-01-22 15:58:49 -08:00
SkeleyM
441ffce4a3 feat(ui): port "create and add tag" to main branch (#711)
* Port create & add tag

* Fix Name Conflict

* Add translation keys

* unify uses of BuildTagPanel

* replace tabs with spaces

* Add tag on creation

* Add Suggestions

* Trigger on return

---------

Co-authored-by: bjorn-out <b.g.out@uva.nl>
2025-01-22 15:56:54 -08:00
mashed5894
778028923e feat(ui): add about section (#712)
* added about section to the help menu and modal to display information

* load image through resource manager

* cleaned up about text

* remove visit github repo menu, moved to about modal

* added function to check ffmpeg version

* fixed version formatting

* copied in ffmpeg checker code from v9.4 with a warning message on startup if ffmpeg is not detected

* mypy fixes

* about.content spacing

* about.content title formatting

* added config path to about screen

* ruff fixes

---------

Co-authored-by: Sean Krueger <skrueger2270@gmail.com>
2025-01-22 15:48:57 -08:00
Weblate (bot)
ea9b57b85f translations: update German, Hungarian, French, Swedish (#697)
* Translated using Weblate (German)

Currently translated at 99.5% (217 of 218 strings)

Co-authored-by: Aaron M <muelleraaron0@users.noreply.hosted.weblate.org>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/
Translation: TagStudio/Strings

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (218 of 218 strings)

Translated using Weblate (Hungarian)

Currently translated at 100.0% (216 of 216 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/
Translation: TagStudio/Strings

* Translated using Weblate (French)

Currently translated at 57.7% (126 of 218 strings)

Co-authored-by: Bamowen <mathieu.monsauret@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/
Translation: TagStudio/Strings

* Translated using Weblate (Swedish)

Currently translated at 34.4% (75 of 218 strings)

Co-authored-by: mashed5894 <mashed5894@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/sv/
Translation: TagStudio/Strings

---------

Co-authored-by: Aaron M <muelleraaron0@users.noreply.hosted.weblate.org>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Co-authored-by: Bamowen <mathieu.monsauret@gmail.com>
Co-authored-by: mashed5894 <mashed5894@gmail.com>
2025-01-22 15:24:04 -08:00
Jann Stute
2a836b0d25 docs: discourage force-pushes on prs that are open for review (#714)
* Update CONTRIBUTING.md

* Update CONTRIBUTING.md
2025-01-19 13:07:40 -08:00
SkeleyM
6ea2c99abb fix: drag and drop no longer resets (#710) 2025-01-17 15:04:13 -08:00
Travis Abendshien
44ff17c0b3 fix: dragging files references correct entry IDs
Fixes #705
2025-01-15 14:23:45 -08:00
Jann Stute
0cdb1a8c06 ui: keyboard navigation for editing tags (#407)
* build_tag modal: make Tag Title selected when opening modal

* build_tag modal: Tab now changes focus when aliases field is in focus

* fix: unpredictable tab order in build tag modal

* feat: implement proper tab order

* ci: fix mypy errors

* fix: merge issue 1

* fix: merge issue 2

* refactor: TagDatabasePanel now inherits from TagSearchPanel for code deduplication

* Revert "refactor: TagDatabasePanel now inherits from TagSearchPanel for code deduplication"

This reverts commit fac589b3e3.
2025-01-14 03:19:44 -08:00
Travis Abendshien
5caf869867 docs: update roadmap 2025-01-13 18:41:08 -08:00
Travis Abendshien
604837fcaa fix: store tag.id to variable before using in lambda
This fixes an issue where every tag added from the "+" button had ID 0 (the "Archived" tag).

Co-Authored-By: Jann Stute <46534683+Computerdores@users.noreply.github.com>
2025-01-13 14:42:19 -08:00
Jann Stute
5c8f2c507f feat: optimise AND queries (#679)
* feat: optimise tag constraint

* feat: use less subqueries

* refactoring: __entry_satisfies_ast was unnecessary

* feat: reduce time consumption of counting total results massively

* feat: log the time it takes to fetch the results

* Revert "feat: reduce time consumption of counting total results massively"

This reverts commit 30af514681.

* feat: log the time it takes to count the results

* feat: optimise __entry_has_all_tags
2025-01-13 13:48:02 -08:00
Jann Stute
5bab00aa6d refactor: TagDatabasePanel now inherits from TagSearchPanel for code deduplication (#699)
* refactor: TagDatabasePanel now inherits from TagSearchPanel for code deduplication

* refactor: rename callback method

* extract creation of row items to separate method
2025-01-13 13:46:57 -08:00
Jann Stute
a272b18637 feat: improve performance of "Delete Missing Entries" (#696)
* feat: Delete all unlinked entries at once (#617)

This technically removes the usefulness progress indicator, but brief
testing on my end had it delete ~8000 entries in less time than it took
me to see if the progress indicator was properly indeterminate or not

* fix(fmt): remove unused import

* fix: wasn't able to delete more than 32766 entries

* chose: ruff check --fix

* fix: address review comment

---------

Co-authored-by: Tobias Berger <toby@tobot.dev>
2025-01-11 13:26:01 -08:00
Travis Abendshien
fce97852d3 feat!: tag categories (#655)
* refactor: remove TagBoxField and TagField (NOT WORKING)

* refactor: remove tag field types

* ci: fix mypy and ruff tests

* refactor: split up preview_panel

* fix: search now uses `TagEntry` (#656)

* fix: move theme check inside class

* refactor: reimplement file previews

* refactor: modularize `file_attributes.py`

* ui: show fields in preview panel

known issues:
- fields to not visually update after being edited until the entries are reloaded from the thumbnail grid (yes, the thumbnail grid)
- add field button currently non-functional
- surprise segfaults

* search: remove TagEntry join

* fix: remove extra `self.filter` assignment

* add success return flag to `add_tags_to_entry()`

* refactor: use entry IDs instead of objects and indices

- fixes preview panel not updating after entry edits
- fixes slow selection performance
- fixes double render call

* feat: add tag categories to preview panel

* ui: add "is category" checkbox in tag panel

* fix: tags can be compared for name sorting

* fix: don't add tags to previous selections

* fix: badges now properly update

* ui: hide sizeGrip

* ui: add blue ui color

* ui: display empty selection; better multi-selection

* cleanup comments; rename tsp to tag_search_panel

* fix(ui): properly unset container callbacks

* fix: optimize queries

* fix: catch int cast exception

* fix: remove unnecessary update calls

* fix: restore try/except block in preview_panel

* fix: correct type hints for get_tag_categories

* fix: tags no longer lazy load subtags and aliases

* fix: recursively include parent tag categories

* chore: update copyright info

* chore: remove unused code

* fix: load fields for selected entry

* refactor: remove `is_connected` from AddFieldModal

* fix: include category tags under their own categories

* fix: badges now update when last tag is removed

* fix: resolve differences with main

* fix: return empty set in place of `None`

* ui: add field highlighting, tweak theming

* refactor!: eradicate use of the term "subtag"

- Removes ambiguity between the use of the term "parent tag" and "subtag"
- Fixes inconstancies between the use of the term "subtag" to refer to either parent tags or child tags
- Fixes duplicate and ambiguous subtags mapped relationship for the Tag model
- Does NOT fix tests

* fix: catch and show library load errors

* tests: fix and/or remove tests

* suppress db preference warnings

* tests: add field container tests

* tests: add tag category tests

* refactor(ui): move recent libraries list to file menu

* docs: update roadmap and docs for tag categories

* fix: restore json migration functionality

* logs: remove/update debug logs

* chore: remove unused code

* tests: remove tests related to `TagBoxWidget`

* ui: optimize selection and badge updates

* docs: update usage

* fix: change typo of `tag.id` to `tag_id`

Co-authored-by: Jann Stute <46534683+Computerdores@users.noreply.github.com>

* fix: use term "child tags" instead of "subtags" in docstring

Co-authored-by: Jann Stute <46534683+Computerdores@users.noreply.github.com>

* fix: reference `child_id` instead of `parent_id` when deleting tags

Co-Authored-By: Jann Stute <46534683+Computerdores@users.noreply.github.com>

* add TODO comment for `update_thumbs()` optimization

* fix: combine and check (most) built-in tag data from JSON

Known issue: Tag colors from built-in JSON tags are not updated. This can be seen in the failing test.

* refactor: rename `select_item()` to `toggle_item_selection()`

* add TODO to optimize `add_tags_to_entry()`

* fix: remove unnecessary joins in search

* Revert "fix: remove unnecessary joins in search"

This reverts commit 4c019ca19c.

* fix: remove unnecessary joins in search

* reremove unused method `get_all_child_tag_ids()`

* fix: migrate user-edited tag colors for built-in tags

* style: update header for contributor-created files

* fix: use absolute path in "open file" context menu

* chore: change paramater type hint

---------

Co-authored-by: python357-1 <jb2101554@gmail.com>
Co-authored-by: Jann Stute <46534683+Computerdores@users.noreply.github.com>
2025-01-11 09:44:09 -08:00
Weblate (bot)
5860a2ca9b translations: update German, Hungarian, Spanish, and Chinese (Traditional Han script) (#677)
* Translated using Weblate (German)

Currently translated at 73.3% (157 of 214 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Jann Stute <jann.stute@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/
Translation: TagStudio/Strings

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Hungarian)

Currently translated at 59.8% (128 of 214 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/
Translation: TagStudio/Strings

* Translated using Weblate (Spanish)

Currently translated at 63.5% (136 of 214 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Nginearing <142851004+Nginearing@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/
Translation: TagStudio/Strings

* Translated using Weblate (Chinese (Traditional Han script))

Currently translated at 94.8% (203 of 214 strings)

Co-authored-by: Brian Su <brisu@me.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/zh_Hant/
Translation: TagStudio/Strings

---------

Co-authored-by: Jann Stute <jann.stute@protonmail.com>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Co-authored-by: Nginearing <142851004+Nginearing@users.noreply.github.com>
Co-authored-by: Brian Su <brisu@me.com>
2025-01-11 07:05:26 -08:00
Travis Abendshien
d8d61cc8c8 docs: fix broken weblate link in README 2025-01-11 07:03:05 -08:00
Travis Abendshien
fc81c43af1 docs: add a linux install notice (#695)
* docs: add a linux install notice (#689)

* docs: add a linux install notice to readme (#690)

---------

Co-authored-by: Qronikarz <84787215+Qronikarz@users.noreply.github.com>
2025-01-11 07:00:13 -08:00
Jann Stute
3cd56a881f feat: sort by "date added" to library (#674)
* ui: add sorting mode dropdown

* feat: pass sorting mode to Library.search_library

* feat: implement sorting by creation date

* ui: add dropdown for sorting direction

* ui: update shown entries after changing sorting mode / direction

* docs: mark sorting by "Date Created" as completed

* fix: remove sorting options that have not been implemented

* fix: rename sorting mode to "Date Added"

* fix: check off the right item on the roadmap

* feat: translate sorting UI

* fix: address review comments
2025-01-10 07:46:23 -08:00
Travis Abendshien
936157c3c2 fix(ui): properly mask macOS icon 2025-01-07 01:17:31 -08:00
Travis Abendshien
c4f4bba5e0 build: update macos bundle identifier and version
Update bundle to use `com.companyname.appname` reverse-domain structure
2025-01-06 11:44:18 -08:00
Travis Abendshien
29c0dfdb2d feat(ui): use tag query as default new tag name 2025-01-05 23:40:41 -08:00
Travis Abendshien
bf03e28fdb ui: update macOS icon 2025-01-05 22:49:58 -08:00
Travis Abendshien
0b6b07d0b4 fix(ui): don't create new QFonts in main_window.py
This fix uses stylesheets instead of initializing new QFonts in the Ui_MainWindow class. This fixes the fonts appearing differently on different OSes, including a fix for text using these QFonts appearing small on macOS. The use of stylesheets also puts the styling in line with how the rest of the program operates.
2025-01-05 21:02:36 -08:00
Travis Abendshien
af760ee61a ui: port splash screen from Alpha-v9.4
Reimplements:
- 7f3b3d06af
- 1e4883c577
- 1c53f05e4f
2025-01-05 19:40:37 -08:00
SkeleyM
c5c86747fe fix: only close add tag menu with no search (#685) 2025-01-05 16:34:55 -08:00
SkeleyM
ef042ef070 fix: call filepaths instead of using start (#667) 2025-01-03 00:37:18 -08:00
Jann Stute
7b672e03a1 feat: implement parent tag search (#673)
* feat: implement parent tag search

* feat: add tests for parent tag search

* fix: typo

* feat: log the time it takes to build the SQL Expression

* feat: instead of hardcoding child tag ids into main query, include subquery

* Revert "feat: instead of hardcoding child tag ids into main query, include subquery"

This reverts commit 2615e7dab4.
2025-01-01 02:36:11 -08:00
python357-1
5a0ba54454 fix: strip whitespace around --open/-o flag (#670)
* fix: fix -o flag not working if path has whitespace around it

* fix: change strip to lstrip/rstrip

* fix: manually expand "~"
2025-01-01 02:35:35 -08:00
Nginearing
d948c0ce4c docs: update readme (#676) 2025-01-01 02:34:18 -08:00
Travis Abendshien
d5cebf39d4 fix: add missing pillow_jxl import
This import was accidentally removed in #569. This commit restores the import.
2024-12-30 20:50:57 -08:00
Weblate (bot)
584f3aa358 translations: remove library.refresh.scanning key (#675)
* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings
2024-12-30 19:18:23 -08:00
Weblate (bot)
1a317a1826 translations: update Hungarian, Polish, French, Chinese (Traditional Han script), Toki Pona (#663)
* Translated using Weblate (Hungarian)

Currently translated at 100.0% (130 of 130 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/
Translation: TagStudio/Strings

* Translated using Weblate (Polish)

Currently translated at 100.0% (130 of 130 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (130 of 130 strings)

Co-authored-by: Eryk Michalak <gnu.ewm@protonmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: qronikarz <qronikarz@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pl/
Translation: TagStudio/Strings

* Translated using Weblate (French)

Currently translated at 100.0% (130 of 130 strings)

Co-authored-by: Bamowen <mathieu.monsauret@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/
Translation: TagStudio/Strings

* Translated using Weblate (Chinese (Traditional Han script))

Currently translated at 90.0% (117 of 130 strings)

Added translation using Weblate (Chinese (Traditional Han script))

Co-authored-by: Brian Su <brisu@me.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/zh_Hant/
Translation: TagStudio/Strings

* Translated using Weblate (Toki Pona)

Currently translated at 96.1% (125 of 130 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: gold <goldstargloww@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tok/
Translation: TagStudio/Strings

---------

Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Co-authored-by: Eryk Michalak <gnu.ewm@protonmail.com>
Co-authored-by: qronikarz <qronikarz@users.noreply.hosted.weblate.org>
Co-authored-by: Bamowen <mathieu.monsauret@gmail.com>
Co-authored-by: Brian Su <brisu@me.com>
Co-authored-by: gold <goldstargloww@gmail.com>
2024-12-30 19:16:46 -08:00
Jann Stute
69aed92f24 feat: translations (#662)
* feat: implement Translator class

* feat: add translate_with_setter and implement formatting of translations

* feat: extend PanelModal to allow for translation

* feat: extend ProgressWidget to allow for translation

* feat: translation in ts_qt.py

* debug: set default lang to DE and show "Not Translated" when replacing untranslated stuff

* add translation todos

* feat: translate modals

* feat: translate more stuff

* fix: UI test wasn't comparing to translated strings

* feat: translations for most of the remaining stuff

* fix: replace debug changes with simpler one

* uncomment debug change

* fix: missing parameter in call

* fix: various review feedback

* fix: don't translate json migration discrepancies list

* fix: typo

* fix: various PR feedback

* fix: correctly read non-ascii characters

* fix: add missing new line at eof

* fix: comment out line of debug code

* fix: address latest review comment

* fix: KeyError that occurred when formatting translations

* fix: regression of d594e84

* fix: add newline to en.json

* fix: organize en.json, fix typo

---------

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
2024-12-30 19:15:39 -08:00
SkeleyM
40bfee0502 fix(ui): prevent duplicate parent tags in UI (#665) 2024-12-23 19:39:23 -08:00
Travis Abendshien
020a73d095 fix(ui): use consistent tag outline colors 2024-12-23 18:55:22 -08:00
Travis Abendshien
431efe4fe9 fix(ui): use correct pink tag color 2024-12-23 18:39:56 -08:00
Travis Abendshien
ca4dc0bebd chore: add 089c8dd to .git-blame-ignore-revs 2024-12-23 16:50:10 -08:00
DandyDev01
82c659c8a4 feat(ui): new tag alias UI (#534)
* updated parents and aliases to use the flowLaout in the build tag panel

added shortcuts for adding and removing aliases and updated the alias ui
to always show remove button and not cover alias

aliases use flowlayout

wrote test for buildTagPanel removeSelectedAlias

parent tags now use flowlayout in build tag panel

moved buttons for adding aliases and parents to be at the end of the
flowLayout

* added aliases and subtags to search results

* aliases now use a table, removed unnecessary keyboard shortcuts

* reverted subtags to regular list from flowlayout

* chor remove redundant lambda

* feat: added display names for tags

* fix: aliases table enter/return and backspace work as expected, display names work as expected, adding aliases outputs them in order

* format

* fix: add parent button on build tag panel

* fix: empty aliases where not being removed all the time

* fix: alias name changes would be discarded when a new alias was created or an alias was removed

* fix: removed display names, as they didn't display properly and should be added in a different PR

* fix: mypy

* fix: added missing session.expunge_all

session.expunge_all() on line 621 was removed, added it back.

* fix: parent_tags relationship in Tag class

parent_tags primaryJoin and secondaryJoin where in the wrong order. They have been switched back to the proper order.

* fix: pillow_jxl import was missing

* fix: ruff

* fix: type hint fixes

* fix: fix the type hint fixes

---------

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
2024-12-22 22:14:37 -08:00
Travis Abendshien
dc2eed431b add .sqlite-journal to .gitignore 2024-12-22 22:11:18 -08:00
Jann Stute
9eed3b64d9 feat: implement search equivalence of "jpg" and "jpeg" filetypes (#649)
* feat: implement search equivalence of "jpg" and "jpeg" filetypes in an extensible manner

* docs: update completion for search features on roadmap

* fix: move FILETYPE_EQUIVALENTS to media_types.py
2024-12-22 13:58:10 -08:00
SkeleyM
4c3ff42169 fix: show correct unlinked files count (#653) 2024-12-22 12:21:04 -08:00
Weblate (bot)
b209abb1a4 translations: propagate en.json key changes (#654)
* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings

* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/
Translation: TagStudio/Strings
2024-12-21 17:29:49 -08:00
Travis Abendshien
45b45f5846 translations: remove unused keys, add missing ones 2024-12-21 15:01:29 -08:00
Travis Abendshien
b3f393e59b style(translations): sort en.json keys 2024-12-21 14:53:56 -08:00
Travis Abendshien
f4b30c15ce refactor(translations): fix + normalize translation keys 2024-12-21 14:50:47 -08:00
Weblate (bot)
8a52bfea69 translations: fix German, add Polish (#650)
* Translated using Weblate (German)

Currently translated at 93.6% (133 of 142 strings)

Translated using Weblate (German)

Currently translated at 87.3% (124 of 142 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Jann Stute <jann.stute@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/
Translation: TagStudio/Strings

* Translated using Weblate (Polish)

Currently translated at 95.7% (136 of 142 strings)

Translated using Weblate (Polish)

Currently translated at 23.2% (33 of 142 strings)

Added translation using Weblate (Polish)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: qronikarz <qronikarz@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pl/
Translation: TagStudio/Strings

---------

Co-authored-by: Jann Stute <jann.stute@protonmail.com>
Co-authored-by: qronikarz <qronikarz@users.noreply.hosted.weblate.org>
2024-12-21 10:31:30 -08:00
SkeleyM
934c98a4d4 fix: enter/return adds top result tag (#651)
* fix return not adding searched tag

* add first_tag_id type hint
2024-12-20 17:00:33 -08:00
Travis Abendshien
36c1c180b3 refactor: consolidate reserved tag values as ints 2024-12-20 16:24:04 -08:00
Travis Abendshien
d6280f7ead style: remove whitespace 2024-12-20 16:07:19 -08:00
Travis Abendshien
933af1c405 ui: update remove tag message box text 2024-12-20 16:00:44 -08:00
Travis Abendshien
2903dd22c4 fix: tags created from tag database now add aliases 2024-12-20 15:56:23 -08:00
DandyDev01
fdfd6490bd feat: delete and create tags from tag database panel (#569)
* [feat] can now add a new tag from the tag library panel

* [feat] can remove tags from the tag library panel
[fix] library panel updates tag list when a new tag is create

* [test] added test for library->remove_tag

* [fix] type error

* removed redundant lambda

Co-authored-by: VasigaranAndAngel <72515046+VasigaranAndAngel@users.noreply.github.com>

* fix: tags with a reserved id could be edited or removed, now they cannot.

* fix: when a tag is removed or edited the preivew panel will update to reflect the changes

Co-authored-by: Sean Krueger <skrueger2270@gmail.com>

* fix: mypy check

* fix: aliases and subtags not being removed from DB when tag they reference was removed.

* feat: added a confirmation message box when removing tags.

* fix: mypy

---------

Co-authored-by: VasigaranAndAngel <72515046+VasigaranAndAngel@users.noreply.github.com>
Co-authored-by: Sean Krueger <skrueger2270@gmail.com>
2024-12-20 15:22:23 -08:00
Travis Abendshien
8387676d79 feat(ui): show filenames in thumbnail grid (Closes #85) (#633)
* feat(ui): add filename label under thumbnails

* refactor(ui): organize menu items

* feat: make thumbnail filenames toggleable

* refactor variables, tweak spacing

* fix(ui): only change cursor on thumb_button

* revert changes to ../search_library/../ts_library.sqlite

* fix: don't ever call .setHidden(False) on visible widgets

* refactor: rename filename toggles to setters

* fix: remove duplicate open_on_start_action
2024-12-20 14:34:05 -08:00
python357-1
24fa76ee30 tests(fix): stop updating sqlite db during tests (#648)
* fix: stop sqlite db from being updated while running tests

* refactor: small refactor in db checking code
2024-12-20 14:03:11 -08:00
Travis Abendshien
9e0c4f39b8 docs: remove closed pr warning from CONTRIBUTING.md 2024-12-14 11:42:17 -08:00
DandyDev01
c33d0203e4 fix: editing tags from preview panel updates database (#641)
* fix: bug where preview_panel tag was out of date compared to tag in database after edits where made using the tagDatabasePanel

* fix: changes made in the preview panel are saved to the database
2024-12-14 11:40:48 -08:00
Travis Abendshien
ebc487eac4 docs: add refactor warning to CONTRIBUTING.md 2024-12-12 21:43:13 -08:00
Travis Abendshien
dec9f1dd28 docs: add additional detail to ffmpeg help 2024-12-11 18:28:09 -08:00
python357-1
a519c9a737 chore: update pytest workflow to 24.04 (#639)
* fix: try fixing pytest workflow

* chore: update pytest workflow to 24.04

* fix: fix libglx package name

* fix: try a different package

* fix: try apt-update first

* Revert "fix: try apt-update first"

This reverts commit 34c04f985b.

* Reapply "fix: try apt-update first"

This reverts commit 775bc2634d.
2024-12-11 17:04:53 -08:00
Sean Krueger
385aaf42d8 feat: reimplement drag drop files (Port #153) (#528)
* feat: Drag and drop files in and out of TagStudio (#153)

* Ability to drop local files in to TagStudio to add to library

* Added renaming option to drop import

* Improved readability and switched to pathLib

* format

* Apply suggestions from code review

Co-authored-by: yed podtrzitko <yedpodtrzitko@users.noreply.github.com>

* Revert Change

* Update tagstudio/src/qt/modals/drop_import.py

Co-authored-by: yed podtrzitko <yedpodtrzitko@users.noreply.github.com>

* Added support for folders

* formatting

* Progress bars added

* Added Ability to Drag out of window

* f

* format

* Ability to drop local files in to TagStudio to add to library

* Added renaming option to drop import

* Improved readability and switched to pathLib

* format

* Apply suggestions from code review

Co-authored-by: yed podtrzitko <yedpodtrzitko@users.noreply.github.com>

* Revert Change

* Update tagstudio/src/qt/modals/drop_import.py

Co-authored-by: yed podtrzitko <yedpodtrzitko@users.noreply.github.com>

* Added support for folders

* formatting

* Progress bars added

* Added Ability to Drag out of window

* f

* format

* format

* formatting and refactor

* format again

* formatting for mypy

* convert lambda to func for clarity

* mypy fixes

* fixed dragout only worked on selected

* Refactor typo, Add license

* Reformat QMessageBox

* Disable drops when no library is open

Co-authored-by: Sean Krueger <skrueger2270@gmail.com>

* Rebased onto SQL migration

* Updated logic to based on selected grid_idx instead of selected ids

* Add newly dragged-in files to SQL database

* Fix buttons being inconsistant across platforms

* Fix ruff formatting

* Rename "override" button to "overwrite"

---------

Co-authored-by: yed podtrzitko <yedpodtrzitko@users.noreply.github.com>
Co-authored-by: Travis Abendshien <lvnvtravis@gmail.com>
Co-authored-by: Sean Krueger <skrueger2270@gmail.com>

* refactor: Update dialog and simplify drop import logic

* Handle Qt events for main window in ts_qt.py

* Replace magic values with enums

* Match import duplicate file dialog to delete missing entry dialog

* Remove excessive progess widgets

* Add docstrings and logging

* refactor: add function for common ProgressWidget use

Extracts the create_progress_bar function from drop_import to the
ProgressWidget class. Instead of creating a ProgressWidget,
FunctionIterator, and CustomRunnable every time a thread-safe progress
widget is needed, the from_iterable function in ProgressWidget now
handles all of that.

---------

Co-authored-by: Creepler13 <denis.schlichting03@gmail.com>
Co-authored-by: yed podtrzitko <yedpodtrzitko@users.noreply.github.com>
Co-authored-by: Travis Abendshien <lvnvtravis@gmail.com>
2024-12-11 16:00:27 -08:00
Travis Abendshien
a1daf5ab6a fix: use absolute ffprobe path on macos (Fix #511) (#629)
* bump pyside version to 6.8.0.1

* fix: try for absolute ffprobe path on macos
2024-12-09 11:51:36 -08:00
Travis Abendshien
aaea0b1475 fix: don't allow blank tag alias values in db (#628) 2024-12-09 11:44:51 -08:00
Jann Stute
a535ed12b0 feat: implement query language (#606)
* add files

* fix: term was parsing ANDList instead of ORList

* make mypy happy

* ruff format

* add missing todo

* add more constraint types

* add parent property to AST

* add BaseVisitor class

* make mypy happy

* add __init__.py

* Revert "make mypy happy"

This reverts commit 926d0dd2e79d06203e84e2f83c06c7fe5b33de23.

* refactoring and fixes

* rudimentary search field integration

* fix: check for None properly

* fix: Entries without Tags are now searchable

* make mypy happy

* Revert "fix: Entries without Tags are now searchable"

This reverts commit 19b40af7480b0c068b81b642b51536a9ec96d030.

* fix: changed joins to outerjoins and added missing outerjoin

* use query lang instead of tag_id FIlterState

* add todos

* fix: remove uncecessary line that broke search when searching for exact name

* fix tag search

* refactoring

* fix: path now uses GLOB operator for proper GLOBs

* refactoring: remove FilterState.id and implement Library.get_entry_full as replacement

* fix: use default value notation instead of if None statement in __post_init__

* remove obsolete Search Mode UI and related code

* ruff fixes

* remove obsolete tests

* fix: item_thumb didn't query entries correctly

* fix: search_library now correctly returns the number of *unique* entries

* make mypy happy

* implement NOT

* remove obsolete filename search

* remove summary as it is not applicable anymore

* finish refactoring of FilterState

* implement special:untagged

* fix: make mypy happy

* Revert changes to search_tags in favor of changes from #604

* fix: also port test changes

* fix: remove unneccessary import

* fix: remove unused dataclass

* fix: AND now works correctly with tags

* simplify structure of parsed AST

* add performance logging

* perf: Improve performance of search by reducing number of required joins from 4 to 1

* perf: double NOT is now optimized out of the AST

* fix: bug where pages would show less than the configured number of entries

* Revert "add performance logging"

This reverts commit c3c7d7546d.

* fix: tag_id search was broken

* somewhat adapt the existing autocompletion to this PR

* perf: Use Relational Division Queries to improve Query Execution Time

* fix: raise Exception so as to not fail silently

* fix: Parser bug broke parentheses

* little bit of clean up

* remove unnecessary comment

* add library for testing search

* feat: add basic tests

* fix: and queries containing just one tag were broken

* chore: remove debug code

* feat: more tests

* refactor: more consistent name for variable

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>

* fix: ruff check complaint over double import

---------

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
2024-12-06 15:43:08 -08:00
Travis Abendshien
056e600466 bump numpy to version 2.1.0 2024-12-05 01:30:18 -08:00
Jann Stute
3196678666 fix: multiple macro errors (#612)
* port fixes from json branch

* fix: correctly pass grid_idx in autofill macro

* fix(BUILD_URL macro): only add url if url was successfully built

* fix(AUTOFILL macro): error when trying to add tag with name that already exists

* fix: test was wrongly renaming sidecar file
2024-12-05 00:43:39 -08:00
Дмитрий
bea6913814 fix: add check to see if library is loaded in filter_items (#547)
* Added a check to see if the library is loaded in filter_items

* Returned check to see if there is an engine

---------

Co-authored-by: gred <gred25@yandex.ru>
2024-12-04 21:53:44 -08:00
Travis Abendshien
b72a2f2331 add ".DS_Store" to GLOBAL_IGNORE_SET 2024-12-04 11:23:42 -08:00
Travis Abendshien
4c33901a47 chore: format with ruff 2024-12-04 11:16:47 -08:00
Travis Abendshien
7d7c8b2348 docs: adjust formatting 2024-12-03 13:04:02 -08:00
Travis Abendshien
47babdd5b5 docs: update README.md and index.md 2024-12-03 12:59:27 -08:00
Weblate (bot)
461d103026 translations: add Filipino translation (#584)
Currently translated at 75.3% (107 of 142 strings)

Translated using Weblate (Filipino)

Currently translated at 50.0% (71 of 142 strings)

Added translation using Weblate (Filipino)



Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fil/
Translation: TagStudio/Strings

Co-authored-by: searinminecraft <114207889+searinminecraft@users.noreply.github.com>
2024-12-03 10:48:23 -08:00
VasigaranAndAngel
a630b09b4f fix: remove/rework windows path tests (#625)
* fix: tagstudio/tests/test_driver.py::test_evaluate_path_last_lib_present always fails in windows.

* refactor: removal tagstudio/tests/test_library.py::test_save_windows_path

Fixes #616
2024-12-03 10:39:44 -08:00
VasigaranAndAngel
8ba23c5d54 fix: clear all setting values when opening a library (#622) 2024-12-02 12:11:39 -08:00
Travis Abendshien
e4d8f995bb docs: remove partial checkboxes 2024-12-01 13:33:39 -08:00
Travis Abendshien
691c63e659 docs: update v9.5 roadmap 2024-12-01 13:24:18 -08:00
Travis Abendshien
1fcd31b62f chore: bump ruff to 0.8.1, pillow-jxl-plugin to 1.3.0 2024-12-01 11:56:10 -08:00
Travis Abendshien
1974ff169c refactor: remove 3.12 nested f-string 2024-11-30 15:11:17 -08:00
Theasacraft
dffa3635b0 fix: remove qt disconnect warning (#613)
* fix: cannot disconnect from None Warning

* fix: cannot disconnect from None Warning mypy compliant
2024-11-30 13:03:57 -08:00
Travis Abendshien
ef68603322 feat(parity): migrate json libraries to sqlite (#604)
* feat(ui): add PagedPanel widget

* feat(ui): add MigrationModal widget

* feat: add basic json to sql conversion

* fix: chose `poolclass` based on file or memory db

* feat: migrate tag colors from json to sql

* feat: migrate entry fields from json to sql

- fix: tag name column no longer has unique constraint
- fix: tags are referenced by id in db queries
- fix: tag_search_panel no longer queries db on initialization; does not regress to empty search window when shown
- fix: tag name search no longer uses library grid FilterState object
- fix: tag name search now respects tag limit

* set default `is_new` case

* fix: limit correct tag query

* feat: migrate tag aliases and subtags from json to sql

* add migration timer

* fix(tests): fix broken tests

* rename methods, add docstrings

* revert tag id search, split tag name search

* fix: use correct type in sidecar macro

* tests: add json migration tests

* fix: drop leading dot from json extensions

* add special characters to json db test

* tests: add file path and entry field parity checks

* fix(ui): tag manager no longer starts empty

* fix: read old windows paths as posix

Addresses #298

* tests: add posix + windows paths to json library

* tests: add subtag, alias, and shorthand parity tests

* tests: ensure no none values in parity checks

* tests: add tag color test, use tag id in tag tests

* tests: fix and optimize tests

* tests: add discrepancy tracker

* refactor: reduce duplicate UI code

* fix: load non-sequential entry ids

* fix(ui): sort tags in the preview panel

* tests(fix): prioritize `None` check over equality

* fix(tests): fix multi "same tag field type" tests

* ui: increase height of migration modal

* feat: add progress bar to migration ui

* fix(ui): sql values update earlier

* refactor: use `get_color_from_str` in test

* refactor: migrate tags before aliases and subtags

* remove unused assertion

* refactor: use `json_migration_req` flag
2024-11-30 13:00:08 -08:00
Travis Abendshien
b7e652ad8d docs: remove db_migration 2024-11-29 15:40:04 -08:00
csponge
bc366fc34d feat: audio playback (#576)
* feat: Audio Playback

Add the ability to play audio files.

Add a slider to seek through an audio file.

Add play/pause and mute/unmute buttons for audio files.

Note: This is a continuation of a mistakenly closed PR:
Ref: https://github.com/TagStudioDev/TagStudio/pull/529

While redoing the changes, I made a couple of improvements.
When the end of the track is reached, the pause button will
swap to the play button and allow the track to be replayed.

Here is the original feature request:
Ref: https://github.com/TagStudioDev/TagStudio/issues/450

* fix: prevent autoplay on new track when paused

* refactor: Add MediaPlayer base class.

Added a MediaPlayer base class per some suggestions
in the PR comments. Hopefully this reduces duplicate code
between the audio/video player in the future.

* refactor: add controls to base MediaPlayer class

Move media controls from the AudioPlayer widget
to the MediaPlayer base class. This removes the need
for a separate AudioPlayer class, and allows the
video player to reuse the media controls.

* fix: position_label update with slider

Update the position_label when the slider is moving.

* fix: replace platform dependent time formatting

Replace the use of `-` in the time format since this
is not availabile on all platforms.

Update initial `position_label` value to '0:00'.
2024-11-29 14:47:27 -08:00
Travis Abendshien
1fb1a80d53 fix: ui/ux parity fixes for thumbnails and files (#608)
* fix(ui): display loading icon before rendered thumb

* fix: skip out of range thumbs

* fix: optimize library refreshing

* fix(ui): tag colors show correct names

* fix(ui): ensure inner field containers are deleted

* fix(ui): don't show default preview label text

* fix: catch all missing file thumbs; clean up logs
2024-11-29 12:35:18 -08:00
Kiril Bourakov
d152cd75d8 fix: "open in explorer" opens correct folder (#603)
* replaced as_posix with str

* replaced addition with f string

---------

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
2024-11-29 09:34:28 -08:00
Jann Stute
20f93719d7 fix(ci): surpress errant mypy warnings (#609)
* fix: mypy error in ts_qt

* fix: mypy error in file_opener due to conflicting types

* fix: remove unnecessary type ignores

* refix type ignore comments

* partially revert "refix type ignore comments" due to being implemented in #608
2024-11-28 13:19:08 -08:00
Travis Abendshien
262893a1bb add .DS_Store to .gitignore 2024-11-27 21:25:03 -08:00
Travis Abendshien
7b2636e4a7 add syncthing to .gitignore 2024-11-24 10:29:29 -08:00
DandyDev01
0d166e63c0 feat(parity): backend for aliases and parent tags (#596)
* backend for aliases and parents

* resolve merge conflics
2024-11-21 12:29:35 -08:00
Travis Abendshien
f6a1ca6783 docs: update contribution guidelines 2024-11-19 17:54:44 -08:00
Coolio
7ae2bc24d6 feat(ui): pre-select default tag name in BuildTagPanel (#592)
This changes the behavior of the tag name inside `BuildTagPanel` for newly created tags:
* The default "New Tag" name is now automatically highlighted
* Blank tag names (including spaces) are no longer allowed to be created
* NOTE: This does not change the tag name column rules in the db, nor does it necessarily need to

***

* [Feature Request]: Make the create tag panel have empty tag name field

* [Feature Request]: Make the create tag panel have empty tag name field

* Revert "[Feature Request]: Make the create tag panel have empty tag name field"

This reverts commit f9c7f5d889.

* [Feature Request]: Make the create tag panel have empty tag name field

* Revert "[Feature Request]: Make the create tag panel have empty tag name field"

This reverts commit e5df3e0f15.

* Update .gitignore

* Updated as per disscussion in issue #591 (DRAFT

* Updated as per disscussion in issue #591 (DRAFT

* Added formatting

* Updated code as per discussion is #592

* Updated code as per discussion is #592 (again)

* Fixed spacing

* Add placeholder text to name field.

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>

* Use universal red color for red border.

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>

* fix: add `src.core.palette` imports

---------

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
2024-11-19 14:14:34 -08:00
Дмитрий
2977e07223 ui: select thumb on press instead of click (#556)
Co-authored-by: gred <gred25@yandex.ru>
2024-11-18 15:35:00 -08:00
DandyDev01
774c886288 fix(ui): update ui when removing fields (#560) 2024-11-18 15:19:28 -08:00
python357-1
bec513f558 feat: add autocomplete for search engine (#586)
* feat: add autocomplete for mediatype, filetype, path, tag, and tag_id searches

* fix: address issues brought up in review

* fix: fix mypy issue

* fix: fix mypy issues for real this time
2024-11-18 10:45:51 -08:00
Justine Akehurst
9078feec0c fix(docs): fix link to feature roadmap page (#594) 2024-11-17 22:03:51 -08:00
Travis Abendshien
f9ef76c2e1 add .idea/ to .gitignore 2024-11-17 16:35:30 -08:00
yed
139836d9c8 fix: stop thumbnail jobs when closing library (#583) 2024-11-14 19:55:16 -08:00
python357-1
fd0df94830 feat: make path search use globs (#582)
* feat: make path search use globs

* fix: specify types in path search

* chore: format with ruff
2024-11-14 14:02:34 -08:00
python357-1
97e0e80f6f feat: add filetype and mediatype searches (#575)
* feat: add filetype and mediatype searches

* style: fix some style issues

* fix: parametrize mediatype and filetype tests

* style: fix remaining unordered import

* style: fix pytest parametrize calls

* feat: add human-readable names to mediacategories

* feat: use human-readable names in mediacategory: search

* feat: add human-readable name to open document

* fix: fix returning multiple filetypes issue and add regression test
2024-11-14 13:52:00 -08:00
Travis Abendshien
fb7ad928af docs(roadmap): add translations to v9.5 2024-11-11 11:13:44 -08:00
python357-1
d75729b578 docs: update CONTRIBUTING.md ruff instructions (#581)
* docs: add warning about ruff on linux

* Update CONTRIBUTING.md

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>

---------

Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
2024-11-08 11:07:51 -08:00
Travis Abendshien
f21d49df7f feat: add JXL thumbnail and animated APNG + WEBP support (port #344 and partially port #357) (#549)
* feat: add JXL image thumbnail support

Co-Authored-By: BPplays <58504799+bpplays@users.noreply.github.com>

* feat: add animated previews for webp and apng

Co-Authored-By: BPplays <58504799+bpplays@users.noreply.github.com>

---------

Co-authored-by: BPplays <58504799+bpplays@users.noreply.github.com>
2024-11-07 15:12:57 -08:00
Travis Abendshien
96026b66bc feat: add OpenDocument thumbnail support (port #366) (#545)
* feat: add OpenDocument thumbnail support

Co-Authored-By: Josh Beatty <joshuatb6@gmail.com>

* tests: add test comparing odt to png snapshot

* tests: add test comparing ods to png snapshot

* test: combine OpenDocument tests

* test: combine compatible preview tests

* test: combine preview render tests

* fix: update test snapshots

---------

Co-authored-by: Josh Beatty <joshuatb6@gmail.com>
2024-11-07 15:00:51 -08:00
Travis Abendshien
c7171c5455 chore: update resources_rc.py 2024-11-07 13:31:13 -08:00
Weblate (bot)
5ee118c1fb translations: update from Hosted Weblate (#579)
* Added translation using Weblate (Russian)

* Translated using Weblate (Russian)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ru/

* Added translation using Weblate (Portuguese)

* Added translation using Weblate (Portuguese (Brazil))

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 46.4% (66 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 46.4% (66 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Added translation using Weblate (Tamil)

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 74.6% (106 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 74.6% (106 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Tamil)

Currently translated at 51.4% (73 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Added translation using Weblate (Spanish)

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Tamil)

Currently translated at 88.0% (125 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (Spanish)

Currently translated at 11.2% (16 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 11.2% (16 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 19.7% (28 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 19.7% (28 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Russian)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ru/

* Translated using Weblate (Spanish)

Currently translated at 29.5% (42 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 29.5% (42 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 49.2% (70 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 49.2% (70 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 52.1% (74 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Added translation using Weblate (Norwegian Bokmål)

* Translated using Weblate (Tamil)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 55.6% (79 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/nb_NO/

* Added translation using Weblate (French)

* Translated using Weblate (Russian)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ru/

* Translated using Weblate (Spanish)

Currently translated at 56.3% (80 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 56.3% (80 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 68.3% (97 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/nb_NO/

* Translated using Weblate (French)

Currently translated at 40.1% (57 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/

* Translated using Weblate (Spanish)

Currently translated at 65.4% (93 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 65.4% (93 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 74.6% (106 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 83.8% (119 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 83.8% (119 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 83.8% (119 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 83.8% (119 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 93.6% (133 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 93.6% (133 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (English)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/en/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Added translation using Weblate (Danish)

* Added translation using Weblate (German)

* Translated using Weblate (Danish)

Currently translated at 1.4% (2 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/da/

* Added translation using Weblate (Cantonese (Traditional Han script))

* Translated using Weblate (Tamil)

Currently translated at 99.2% (141 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (German)

Currently translated at 2.8% (4 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Added translation using Weblate (Hungarian)

* Translated using Weblate (German)

Currently translated at 14.0% (20 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Translated using Weblate (Hungarian)

Currently translated at 99.2% (141 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/

* Translated using Weblate (German)

Currently translated at 14.7% (21 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Added translation using Weblate (Swedish)

* Translated using Weblate (German)

Currently translated at 71.8% (102 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Translated using Weblate (Swedish)

Currently translated at 78.8% (112 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/sv/

* Added translation using Weblate (Toki Pona)

* Translated using Weblate (Tamil)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (Danish)

Currently translated at 2.8% (4 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/da/

* Translated using Weblate (Toki Pona)

Currently translated at 83.0% (118 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tok/

* Added translation using Weblate (Italian)

* Translated using Weblate (French)

Currently translated at 64.0% (91 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/

* Translated using Weblate (German)

Currently translated at 76.0% (108 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Translated using Weblate (Hungarian)

Currently translated at 99.2% (141 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/

* Translated using Weblate (Toki Pona)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tok/

* Translated using Weblate (Italian)

Currently translated at 11.2% (16 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/it/

* Added translation using Weblate (Turkish)

* Translated using Weblate (Turkish)

Currently translated at 88.7% (126 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tr/

* Translated using Weblate (Turkish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tr/

* Translated using Weblate (English)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/en/

* Translated using Weblate (French)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/

* Translated using Weblate (English)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/en/

* Translated using Weblate (French)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/

* Translated using Weblate (Russian)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ru/

* Translated using Weblate (Portuguese)

Currently translated at 0.0% (0 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt/

* Translated using Weblate (Portuguese)

Currently translated at 0.0% (0 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Tamil)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 67.6% (96 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/nb_NO/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 67.6% (96 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/nb_NO/

* Translated using Weblate (French)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/

* Translated using Weblate (Danish)

Currently translated at 2.8% (4 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/da/

* Translated using Weblate (Danish)

Currently translated at 2.8% (4 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/da/

* Translated using Weblate (German)

Currently translated at 76.0% (108 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Translated using Weblate (German)

Currently translated at 76.0% (108 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Translated using Weblate (German)

Currently translated at 76.0% (108 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Translated using Weblate (Cantonese (Traditional Han script))

Currently translated at 0.0% (0 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/yue_Hant/

* Translated using Weblate (Cantonese (Traditional Han script))

Currently translated at 0.0% (0 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/yue_Hant/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/

* Translated using Weblate (Swedish)

Currently translated at 78.8% (112 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/sv/

* Translated using Weblate (Swedish)

Currently translated at 78.8% (112 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/sv/

* Translated using Weblate (Swedish)

Currently translated at 78.8% (112 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/sv/

* Translated using Weblate (Toki Pona)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tok/

* Translated using Weblate (Italian)

Currently translated at 11.2% (16 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/it/

* Translated using Weblate (Italian)

Currently translated at 11.2% (16 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/it/

* Translated using Weblate (Italian)

Currently translated at 11.2% (16 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/it/

* Translated using Weblate (Turkish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tr/

* Update translation files

Updated by "Remove blank strings" add-on in Weblate.

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/

---------

Co-authored-by: Artyom Ognev <greatprincestolas@gmail.com>
Co-authored-by: Space_Fox <indtekworldbaj99@gmail.com>
Co-authored-by: Lobo Metalúrgico <hugolino1000@gmail.com>
Co-authored-by: Vasi <vasigaranvip195@gmail.com>
Co-authored-by: Nginearing <leonmarshall08@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Bamowen <mathieu.monsauret@gmail.com>
Co-authored-by: Ryussei <weblate.or30w@aleeas.com>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Co-authored-by: Zoinx <ammesammegaming@gmail.com>
Co-authored-by: gold <goldstargloww@gmail.com>
Co-authored-by: William de Castro <williamtdcastro@gmail.com>
Co-authored-by: Jann Stute <jann.stute@protonmail.com>
Co-authored-by: Nyghl <hknimre@gmail.com>
Co-authored-by: Obscaeris <mathysuzin@gmail.com>
2024-11-07 12:01:43 -08:00
Travis Abendshien
fc4e124cd8 Merge branch 'main' of github.com:TagStudioDev/TagStudio 2024-11-05 10:25:30 -08:00
Travis Abendshien
15bf354c88 docs(roadmap): add drag and drop 2024-11-05 10:25:27 -08:00
Travis Abendshien
10abd18def docs(roadmap): add thumbnail overrides 2024-11-05 10:24:44 -08:00
Travis Abendshien
73daa39bf1 docs(roadmap): clarify filetype search 2024-11-05 10:20:28 -08:00
Дмитрий
0358f51f99 feat: add IMAGE_RASTER_TYPES (Fix #550) (#551)
* fix resolution info

* Fix for Raw and Vector Image types

* Small refactor

* Create IMAGE_RASTER_TYPES and remove is_image_ext_raster

* Change if statment only for raster

* Rename _IMAGE_SET to _IMAGE_RASTER_SET

---------

Co-authored-by: gred <gred25@yandex.ru>
2024-11-04 12:28:44 -08:00
Hissymaster
e02eb39ae2 docs: change reference to planned_features.md to roadmap.md (#564)
Co-authored-by: Hissymaster <Hissymaster@gmail.com>
2024-10-28 20:46:27 -07:00
Travis Abendshien
6e5a1a0e52 docs: add issues numbers to roadmap 2024-10-28 14:38:34 -07:00
Travis Abendshien
2376380245 docs: remove planned_features.md 2024-10-28 13:02:05 -07:00
Travis Abendshien
04149f6454 docs: add feature roadmap 2024-10-28 13:01:13 -07:00
Travis Abendshien
d3c3e634b9 feat: add ePub thumbnail support (port #387) (#539)
* feat: add ePub thumbnail support

Co-Authored-By: Jorge Rui Da Silva Barrios <29062316+jorgerui@users.noreply.github.com>

* tests: compare epub cover against png snapshot

Co-Authored-By: yed <yedpodtrzitko@users.noreply.github.com>

* test: optimize epub test file

---------

Co-authored-by: Jorge Rui Da Silva Barrios <29062316+jorgerui@users.noreply.github.com>
Co-authored-by: yed <yedpodtrzitko@users.noreply.github.com>
2024-10-17 15:15:51 -07:00
Travis Abendshien
3d7629bc73 feat: add pdf thumbnail support (port #378) (#543)
* feat: add pdf thumbnail support

Co-Authored-By: Heiholf <71659566+heiholf@users.noreply.github.com>

* fix: remove redef

* tests: add test comparing pdf to png snapshot

Co-Authored-By: yed <yedpodtrzitko@users.noreply.github.com>

* fix: fix info in docstrings

* fix: remove sample png generation

* fix: change the pdf snapshot to use a black square

* chore: fix whitespace

---------

Co-authored-by: Heiholf <71659566+heiholf@users.noreply.github.com>
Co-authored-by: yed <yedpodtrzitko@users.noreply.github.com>
2024-10-14 16:34:49 -07:00
Travis Abendshien
9255a86ad1 feat: add svg thumbnail support (port #442) (#540)
* feat: add svg thumbnail support

Co-Authored-By: Tyrannicodin <86689800+Tyrannicodin@users.noreply.github.com>

* flip `svg.isValid()` logic check

* tests: add test comparing svg to png snapshot

Co-Authored-By: yed <yedpodtrzitko@users.noreply.github.com>

---------

Co-authored-by: Tyrannicodin <86689800+Tyrannicodin@users.noreply.github.com>
Co-authored-by: yed <yedpodtrzitko@users.noreply.github.com>
2024-10-14 13:30:46 -07:00
Travis Abendshien
5b85462cfa ci: pin pytest ubuntu version to 22..04 (#544) 2024-10-12 23:59:08 -07:00
xarvex
abeb0c1ce3 fix(ci): complete 7c253226d5 2024-10-11 17:12:57 -05:00
xarvex
7c253226d5 fix(ci): replace obselete package 2024-10-11 17:01:49 -05:00
Travis Abendshien
68c166d8d3 Bump version to v9.5.0 Experimental 2024-10-10 12:40:09 -07:00
Jann Stute
c348c763f8 fix: enable mypy to run from project directory (#520) 2024-10-07 19:04:22 -07:00
yed
7574ad3846 fix: don't check db version with new library (#536) 2024-10-07 18:56:02 -07:00
Travis Abendshien
7dd0f3dabb feat: port thumbnail (#390) and related features to v9.5 (#522)
* feat: port v9.4 thumbnail + related feats to v9.5

Ports the following thumbnail and related PRs from the `Alpha-v9.4` branch to `main` (v9.5+):
- (#273) Blender thumbnail support
- (#307) Add font thumbnail preview support
- (#331) refactor: move type constants to new media classes
- (#390) feat(ui): expanded thumbnail and preview features
- (#370) ui: "open in explorer" action follows os name
- (#373) feat(ui): preview support for source engine files
- (#274) Refactor video_player.py (Fix #270)
- (#430) feat(ui): show file creation/modified dates + restyle path label
- (#471) fix(ui): use default audio icon if ffmpeg is absent
- (#472) fix(ui): use birthtime for creation time on mac & win

Co-Authored-By: Ethnogeny <111099761+050011-code@users.noreply.github.com>
Co-Authored-By: Theasacraft <91694323+Thesacraft@users.noreply.github.com>
Co-Authored-By: SupKittyMeow <77246128+supkittymeow@users.noreply.github.com>
Co-Authored-By: EJ Stinson <93455158+favroitegamers@users.noreply.github.com>
Co-Authored-By: Sean Krueger <71362472+seakrueger@users.noreply.github.com>

* remove vscode exceptions from `.gitignore`

* delete .vscode directory

* style: format for `ruff check`

* fix(tests): update `test_update_widgets_not_selected` test

* remove Send2Trash dependency

* refactor: use dataclass for MediaCateogry

* refactor: use enums for UI colors

* docs: add file docstring for silent_Popen

* refactor: replace logger with structlog

* use early return inside `ResourceManager.get()`

* add `is_ext_in_category()` method to `MediaCategory`

Add method to check if an extension is a member of a given MediaCategory.

* style: fix docstring style, missing type hints, rename `afm`

* fix: use structlog vars in logging

* refactor: move platform-dependent strings to PlatformStrings

* refactor: move `parents[2]` path to variable

* fix: undo logger regressions

---------

Co-authored-by: Ethnogeny <111099761+050011-code@users.noreply.github.com>
Co-authored-by: Theasacraft <91694323+Thesacraft@users.noreply.github.com>
Co-authored-by: SupKittyMeow <77246128+supkittymeow@users.noreply.github.com>
Co-authored-by: EJ Stinson <93455158+favroitegamers@users.noreply.github.com>
Co-authored-by: Sean Krueger <71362472+seakrueger@users.noreply.github.com>
2024-10-07 14:14:01 -07:00
yed
e0752828db feat: store Entry suffix separately (#503)
* feat: save entry suffix separately

* change LibraryPrefs to allow identical values, add test
2024-10-07 14:09:57 -07:00
Travis Abendshien
1c7aaf0a16 Revert "translations: update from Hosted Weblate (#530)"
This reverts commit fe207062d5.
2024-10-02 14:48:01 -07:00
Weblate (bot)
fe207062d5 translations: update from Hosted Weblate (#530)
* Added translation using Weblate (Russian)

* Translated using Weblate (Russian)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ru/

* Added translation using Weblate (Portuguese)

* Added translation using Weblate (Portuguese (Brazil))

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 46.4% (66 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 46.4% (66 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Added translation using Weblate (Tamil)

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 74.6% (106 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 74.6% (106 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Tamil)

Currently translated at 51.4% (73 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Added translation using Weblate (Spanish)

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Tamil)

Currently translated at 88.0% (125 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (Spanish)

Currently translated at 11.2% (16 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 11.2% (16 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 19.7% (28 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 19.7% (28 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Russian)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ru/

* Translated using Weblate (Spanish)

Currently translated at 29.5% (42 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 29.5% (42 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 49.2% (70 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 49.2% (70 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 52.1% (74 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Added translation using Weblate (Norwegian Bokmål)

* Translated using Weblate (Tamil)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 55.6% (79 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/nb_NO/

* Added translation using Weblate (French)

* Translated using Weblate (Russian)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ru/

* Translated using Weblate (Spanish)

Currently translated at 56.3% (80 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 56.3% (80 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 68.3% (97 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/nb_NO/

* Translated using Weblate (French)

Currently translated at 40.1% (57 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/

* Translated using Weblate (Spanish)

Currently translated at 65.4% (93 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 65.4% (93 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 74.6% (106 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 83.8% (119 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 83.8% (119 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 83.8% (119 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 83.8% (119 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 93.6% (133 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 93.6% (133 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (English)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/en/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Added translation using Weblate (Danish)

* Added translation using Weblate (German)

* Translated using Weblate (Danish)

Currently translated at 1.4% (2 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/da/

* Added translation using Weblate (Cantonese (Traditional Han script))

* Translated using Weblate (Tamil)

Currently translated at 99.2% (141 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (German)

Currently translated at 2.8% (4 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Added translation using Weblate (Hungarian)

* Translated using Weblate (German)

Currently translated at 14.0% (20 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Translated using Weblate (Hungarian)

Currently translated at 99.2% (141 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/

* Translated using Weblate (German)

Currently translated at 14.7% (21 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Added translation using Weblate (Swedish)

* Translated using Weblate (German)

Currently translated at 71.8% (102 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Translated using Weblate (Swedish)

Currently translated at 78.8% (112 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/sv/

* Added translation using Weblate (Toki Pona)

* Translated using Weblate (Tamil)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (Danish)

Currently translated at 2.8% (4 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/da/

* Translated using Weblate (Toki Pona)

Currently translated at 83.0% (118 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tok/

* Added translation using Weblate (Italian)

* Translated using Weblate (French)

Currently translated at 64.0% (91 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/

* Translated using Weblate (German)

Currently translated at 76.0% (108 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Translated using Weblate (Hungarian)

Currently translated at 99.2% (141 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/

* Translated using Weblate (Toki Pona)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tok/

* Translated using Weblate (Italian)

Currently translated at 11.2% (16 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/it/

* Added translation using Weblate (Turkish)

* Translated using Weblate (Turkish)

Currently translated at 88.7% (126 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tr/

* Translated using Weblate (Turkish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tr/

* Translated using Weblate (English)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/en/

* Translated using Weblate (French)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/

* Translated using Weblate (English)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/en/

* Translated using Weblate (French)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/

---------

Co-authored-by: Artyom Ognev <greatprincestolas@gmail.com>
Co-authored-by: Space_Fox <indtekworldbaj99@gmail.com>
Co-authored-by: Lobo Metalúrgico <hugolino1000@gmail.com>
Co-authored-by: Vasi <vasigaranvip195@gmail.com>
Co-authored-by: Nginearing <leonmarshall08@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Bamowen <mathieu.monsauret@gmail.com>
Co-authored-by: Ryussei <weblate.or30w@aleeas.com>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Co-authored-by: Zoinx <ammesammegaming@gmail.com>
Co-authored-by: gold <goldstargloww@gmail.com>
Co-authored-by: William de Castro <williamtdcastro@gmail.com>
Co-authored-by: Jann Stute <jann.stute@protonmail.com>
Co-authored-by: Nyghl <hknimre@gmail.com>
Co-authored-by: Obscaeris <mathysuzin@gmail.com>
2024-10-01 17:12:07 -07:00
Travis Abendshien
02ac69978d Revert "translations: update from Hosted Weblate (#526)"
This reverts commit c37c4a95a7.
2024-10-01 17:07:01 -07:00
Weblate (bot)
c37c4a95a7 translations: update from Hosted Weblate (#526)
* Added translation using Weblate (Russian)

* Translated using Weblate (Russian)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ru/

* Added translation using Weblate (Portuguese)

* Added translation using Weblate (Portuguese (Brazil))

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 46.4% (66 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 46.4% (66 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Added translation using Weblate (Tamil)

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 74.6% (106 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 74.6% (106 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Tamil)

Currently translated at 51.4% (73 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Added translation using Weblate (Spanish)

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/

* Translated using Weblate (Tamil)

Currently translated at 88.0% (125 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (Spanish)

Currently translated at 11.2% (16 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 11.2% (16 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 19.7% (28 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 19.7% (28 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Russian)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ru/

* Translated using Weblate (Spanish)

Currently translated at 29.5% (42 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 29.5% (42 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 49.2% (70 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 49.2% (70 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 52.1% (74 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Added translation using Weblate (Norwegian Bokmål)

* Translated using Weblate (Tamil)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 55.6% (79 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/nb_NO/

* Added translation using Weblate (French)

* Translated using Weblate (Russian)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ru/

* Translated using Weblate (Spanish)

Currently translated at 56.3% (80 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 56.3% (80 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 68.3% (97 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/nb_NO/

* Translated using Weblate (French)

Currently translated at 40.1% (57 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/

* Translated using Weblate (Spanish)

Currently translated at 65.4% (93 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 65.4% (93 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 74.6% (106 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 83.8% (119 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 83.8% (119 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 83.8% (119 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 83.8% (119 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 93.6% (133 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 93.6% (133 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (English)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/en/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/

* Added translation using Weblate (Danish)

* Added translation using Weblate (German)

* Translated using Weblate (Danish)

Currently translated at 1.4% (2 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/da/

* Added translation using Weblate (Cantonese (Traditional Han script))

* Translated using Weblate (Tamil)

Currently translated at 99.2% (141 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (German)

Currently translated at 2.8% (4 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Added translation using Weblate (Hungarian)

* Translated using Weblate (German)

Currently translated at 14.0% (20 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Translated using Weblate (Hungarian)

Currently translated at 99.2% (141 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/

* Translated using Weblate (German)

Currently translated at 14.7% (21 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Added translation using Weblate (Swedish)

* Translated using Weblate (German)

Currently translated at 71.8% (102 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Translated using Weblate (Swedish)

Currently translated at 78.8% (112 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/sv/

* Added translation using Weblate (Toki Pona)

* Translated using Weblate (Tamil)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/

* Translated using Weblate (Danish)

Currently translated at 2.8% (4 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/da/

* Translated using Weblate (Toki Pona)

Currently translated at 83.0% (118 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tok/

* Added translation using Weblate (Italian)

* Translated using Weblate (French)

Currently translated at 64.0% (91 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/

* Translated using Weblate (German)

Currently translated at 76.0% (108 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/de/

* Translated using Weblate (Hungarian)

Currently translated at 99.2% (141 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/

* Translated using Weblate (Toki Pona)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tok/

* Translated using Weblate (Italian)

Currently translated at 11.2% (16 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/it/

* Added translation using Weblate (Turkish)

* Translated using Weblate (Turkish)

Currently translated at 88.7% (126 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tr/

* Translated using Weblate (Turkish)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tr/

* Translated using Weblate (English)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/en/

* Translated using Weblate (French)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/

* Translated using Weblate (English)

Currently translated at 100.0% (142 of 142 strings)

Translation: TagStudio/Strings
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/en/

* fix: remove unused strings and sort lists

* chore: update .git-blame-ignore-revs

---------

Co-authored-by: Artyom Ognev <greatprincestolas@gmail.com>
Co-authored-by: Space_Fox <indtekworldbaj99@gmail.com>
Co-authored-by: Lobo Metalúrgico <hugolino1000@gmail.com>
Co-authored-by: Vasi <vasigaranvip195@gmail.com>
Co-authored-by: Nginearing <leonmarshall08@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Bamowen <mathieu.monsauret@gmail.com>
Co-authored-by: Ryussei <weblate.or30w@aleeas.com>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Co-authored-by: Zoinx <ammesammegaming@gmail.com>
Co-authored-by: gold <goldstargloww@gmail.com>
Co-authored-by: William de Castro <williamtdcastro@gmail.com>
Co-authored-by: Jann Stute <jann.stute@protonmail.com>
Co-authored-by: Nyghl <hknimre@gmail.com>
Co-authored-by: Travis Abendshien <lvnvtravis@gmail.com>
2024-09-27 15:21:51 -07:00
Travis Abendshien
49d071cf2b docs: add weblate link to readme 2024-09-22 20:27:40 -07:00
Bamowen
4cd70d2c4f add string tokens for en.json (#507)
* Add en.json with strings found in code

* remove unused, internal, and logging strings

This removes any string tokens for unused/unfinished features, internally facing code, and log outputs.

---------

Co-authored-by: Travis Abendshien <lvnvtravis@gmail.com>
2024-09-22 20:18:34 -07:00
FB100
073d51734b fix: correct typo in test_driver.py comment (#496) 2024-09-13 17:26:05 -07:00
Travis Abendshien
e51da278fa squash .git-blame-ignore.revs 2024-09-13 00:30:48 -07:00
Travis Abendshien
b6e2167605 ci(ruff)!: update ruff linter config, refactor to comply (#499)
* ci: update ruff linter config

- Set line length to 100
- Enforce Google-style docstrings
- Lint docstrings and imports

* ci(ruff): exclude missing docstring warnings

* ci(ruff): exclude docstring checks from tests dir

* fix(ruff): change top level linter setting

Fix Ruff warning: `warning: The top-level linter settings are deprecated in favour of their counterparts in the `lint` section. Please update the following options in `pyproject.toml`:
  - 'per-file-ignores' -> 'lint.per-file-ignores'`.

* chore: format with ruff

* add `.git-blame-ignore-revs`

* ci(ruff): add E402 and F541 checks

* ci(ruff): add FBT003 check (#500)

* ci(ruff): add T20 check

* ci(ruff)!: add N check, refactor method names

* ci(ruff): add E501 check, refactor strings

Much commented-out code is removed in this commit.

* update `.git-blame-ignore.revs`

---------

Co-authored-by: yed <yedpodtrzitko@users.noreply.github.com>
2024-09-13 00:28:00 -07:00
yed
c15963868e feat: make search results more ergonomic (#498) 2024-09-12 17:34:27 -07:00
Travis Abendshien
a8fdae8ebc docs: refer to conventional commits in CONTRIBUTING.md
Co-Authored-By: Xarvex <60973030+xarvex@users.noreply.github.com>
2024-09-12 15:58:08 -07:00
Tyrannicodin
2f2f763a29 fix(search): remove wildcard requirement for tags (#481)
* Fix tag search to not require wildcards

* Add partial tag check to test_tag_search

* chore: format with ruff

---------

Co-authored-by: Tyrannicodin <tyrannicodin@gmail.com>
Co-authored-by: Travis Abendshien <lvnvtravis@gmail.com>
2024-09-12 15:02:56 -07:00
yed
4942d1633c refactor: cleanup the refresh_dir code, update tests (#494)
* feat: take Ignore List into consideration when refreshing directory

* undo the extension check in refresh_dir
2024-09-12 14:54:20 -07:00
yed
af642a7d29 fix: prevent error on closing library (#484) 2024-09-10 01:31:33 -07:00
Sean Krueger
2e8efa288d fix(flake): add missing x11 dependency (#478) 2024-09-09 11:34:55 -07:00
Travis Abendshien
fb949b82b7 Revert "ci: add README.md to publish_docs workflow"
This reverts commit 98f4246ff4.
2024-09-08 22:36:03 -07:00
Travis Abendshien
98f4246ff4 ci: add README.md to publish_docs workflow 2024-09-08 22:19:21 -07:00
Travis Abendshien
d75d344439 fix(docs): use valid note callout 2024-09-08 22:13:03 -07:00
Travis Abendshien
aeb7972206 docs: add SQL warning to CONTRIBUTING.md 2024-09-08 22:08:45 -07:00
Travis Abendshien
693a7bc160 docs: update top README warnings 2024-09-08 22:08:37 -07:00
yed
e5e7b8afc6 refactor!: use SQLite and SQLAlchemy for database backend (#332)
* use sqlite + sqlalchemy as a database backend

* change entries getter

* page filterstate.page_size persistent

* add test for entry.id filter

* fix closing library

* fix tag search, adding field

* add field position

* add fields reordering

* use folder

* take field position into consideration

* fix adding tag

* fix test

* try to catch the correct exception, moron

* dont expunge subtags

* DRY models

* rename LibraryField, add is_default property

* remove field.position unique constraint
2024-09-08 22:06:01 -07:00
Sean Krueger
67f7e4dcf9 fix(docs): use correct formatting on FFmpeg help page (#475)
* fix: Add spacing between list elements

* fix: Add title and fixup headers
2024-09-08 11:11:29 -07:00
Sean Krueger
99d3235774 docs: add ffmpeg installation guide (#473)
* docs: Add ffmpeg installation guide

* docs: Add discord invite link

* grammar

* spelling
2024-09-08 10:29:00 -07:00
Bamowen
60cad202da docs: add discord server link in CONTRIBUTING.md (#474) 2024-09-08 10:28:13 -07:00
Knaughty
9b5c26a61e fix(docs): correct grammar mistake in CONTRIBUTING.md. (#452)
Removed unnecessary with in "- Lint code *with* by [doing x]"
2024-09-07 20:34:11 -07:00
Travis Abendshien
f472d22e10 ci: add publish_docs.yaml to publish_docs paths 2024-09-07 07:39:28 -07:00
CarterPillow
844dae0f58 fix(ci): update site_url in mkdocs.yml (#467)
Configure MkDocs to use the custom domain: `docs.tagstud.io`
2024-09-07 07:34:20 -07:00
Travis Abendshien
d04d3b1f0a ci: specify push paths for publish_docs 2024-09-07 07:30:08 -07:00
Travis Abendshien
686e803f3e ci: add CNAME docs.tagstud.io 2024-09-07 00:35:19 -07:00
Travis Abendshien
a8f9bec65c ci: route mkdocs edit_uri to blob/main/docs 2024-09-07 00:20:06 -07:00
xarvex
0b56e7344f fix(ci): single character typo for mkdocs 2024-09-07 01:30:25 -05:00
Paul Friederichsen
af4ef217a5 ci: use MkDocs for documentation site (#460)
* Use MkDocs for documentation

Using Material for MkDocs

* Enable edit buttons on pages

* Updates to mkdocs.yml
2024-09-06 23:10:39 -07:00
Travis Abendshien
8469131006 docs: add ffmpeg requirement 2024-09-03 16:32:47 -07:00
xarvex
3e2fb1282c feat(flake): expose formatter
Fixes: #433
2024-09-03 00:12:03 -05:00
xarvex
3e950a0cbe fix(direnv)!: gitignore .envrc
A common workflow is to have a local .envrc, allow contributors to do
so. Still provide the recommended Nix-based setup, for those who wish to
use it.
That file can then be copied to or symlinked to `.envrc`.
2024-09-01 21:28:58 -05:00
xarvex
38626ac690 chore(direnv): update .envrc
- Cleanup direnv-root file
- Set filetype for vi-like editors
- Format and lint according to shellcheck and shfmt
2024-08-31 13:16:30 -05:00
xarvex
bc38e568fa feat(flake): remove impurity, update nix-direnv
Use path as an input that can be overriden automatically when direnv is
in use.
nix-direnv version present in .envrc has been updated, using watch_file on the flake is already handled.
2024-08-30 14:44:22 -05:00
Florian Zier
4b35df0924 fix(flake): GPU hardware acceleration
* Enable hardware acceleration for Nix devenv

Section "nativeBuildInputs" needs the dependency "qt6.full" to provide hardware acceleration in QT.
Library "wayland" is needed to create a proper OpenGL context under Wayland as well.

Provide a check for open AMD driver and use it for VDPAU video hardware acceleration.

Move "wrapQtAppsHook" to it's correct place under "nativeBuildInputs".

* Add xorg.libXrandr for hardware accelerated video playback.

Using libva and openssl libraries eliminates the need for a dependency on the qt6.full library.
2024-08-29 23:49:00 -05:00
xarvex
750cbf0f9c fix(flake): add missing media dependencies
Fixes: #417

Did not opt for setting VDPAU_DRIVER, should be done on user side
See: https://wiki.archlinux.org/title/Hardware_video_acceleration#Configuring_VA-API
2024-08-29 19:38:23 -05:00
xarvex
cb4798b715 feat(flake): complete revamp with devenv/direnv
Not perfect, and mostly a port of the previous edition. Hours have
already been sunk into this, and need to get this out for consumption,
and for ironing out.
For more information see: https://devenv.sh

NOTE: impure is used only because of the devenv-managed state, do not be
alarmed!
2024-08-24 22:57:00 -05:00
Xarvex
e1b1ef9888 Merge pull request #229 from seakrueger/flake-setup-venv
ci(flake): create and activate venv via Nix Flake
2024-08-22 20:09:24 -05:00
UnusualEgg
3fcf6022b9 refactor: combine open launch args (#364)
Combine the `--open` and `-o` launch arguments into a single argument option.
2024-08-22 18:02:03 -07:00
Travis Abendshien
ec960f2372 (fix): use .get() to avoid KeyError (#347) 2024-08-11 19:01:08 -07:00
Sam
ce87b11fbd Fix #2 for Add Library Tags panel (#328)
The "Add Tags" panel displays all tags when no search has been performed. Modifies the "Add Library Tags panel" to be the same.
2024-07-22 06:59:43 -07:00
Travis Abendshien
c79086f715 Fix collation data not clearing on library close 2024-07-04 17:40:19 -07:00
Travis Abendshien
9ce07bd369 Bump version to 9.3.2 2024-07-03 17:41:21 -07:00
Theasacraft
33ee27a84f Fix small bug (#306) 2024-07-03 17:02:59 -07:00
Travis Abendshien
1204d2b7b5 Fix search ignoring case of extension list 2024-06-21 11:28:12 -07:00
Sean Krueger
15ee13c7b4 Bump Qt6 version to 6.7.1 2024-06-17 13:05:17 -05:00
Xarvex
49ad8117ef fix(flake): resolve mypy access to libraries 2024-06-17 13:05:17 -05:00
Sean Krueger
4f193613de Update Contributing documentation for dev on Nix
Moves the previous updated blurb from the README to the new CONTRIBUTING
file. Also reworks some wording to link to the Flake nix wiki page for
nix users who haven't enable flakes yet.
2024-06-17 13:05:17 -05:00
Sean Krueger
31038711f2 Install ruff via nixpkgs 2024-06-17 13:05:17 -05:00
Sean Krueger
cc827108ef Add xcb as fallback when wayland fails to load
Mostly as a fallback for xserver.
2024-06-17 13:05:17 -05:00
Sean Krueger
9fec4822c1 Setup and activate virtual environment via flake
When using the nix flake to generate a development shell, the python
virtual environment will now automatically be created and dependecies
from both requirements.txt and requirements-dev.txt will be installed.
This removes the need for using the setup script after entering the
dev shell. Exec bash must be the last thing called, as any other
commands past it will not get executed by the shell hook. Also removes
some duplicate dependencies that I found.
2024-06-17 13:05:17 -05:00
Travis Abendshien
501ab1f977 Update issue templates to ask for title 2024-06-16 19:54:56 -07:00
Theasacraft
b3c01e180a Update to pyside6 version 6.7.1 (#223)
* Update to pyside6.7.1

* Fix Ruff

* Fix MyPy

* Update mypy job to also use PySide6 6.7.1

* Remove unused imports

* Add Description to class

* Ruff format

* Fix Warning in pagination.py

* Probably fix Pyside app test

* Rename CustomQPushButton to QPushButtonWrapper
also renamed custom_qbutton.py to qbutton_wrapper.py
2024-06-16 16:53:38 -07:00
Jiri
4c6ebec529 refactoring: centralize field IDs (#157)
* use enum with named fields instead of ad-hoc numbers

* move tag ids into constants file
2024-06-16 14:24:48 -07:00
Travis Abendshien
5c25666e67 Fix TypeError in folders_to_tags.py
- Additionally use proper comparison syntax
2024-06-15 13:19:28 -07:00
Lennart S
fae65bd9e9 docs: Fixed broken markdown doc link (#291) 2024-06-15 13:10:55 -07:00
Jiri
8e065ca8ac create testing library files ad-hoc (#292) 2024-06-14 10:11:00 -07:00
Travis Abendshien
82946cb0b8 Update CONTRIBUTING.md with PyTest info 2024-06-13 15:39:13 -07:00
Jiri
aa2925cde0 add pytest to CI pipeline (#286) 2024-06-13 15:29:22 -07:00
Travis Abendshien
5bc80a043f Update tagstudio.spec 2024-06-13 09:17:14 -07:00
Travis Abendshien
65d88b9987 Refactor video_player.py (Fix #270) (#274)
* Refactor video_player.py

- Move icons files to qt/images folder, some being renamed
- Reduce icon loading to single initial import
- Tweak icon dimensions and animation timings
- Remove unnecessary commented code
- Remove unused/duplicate imports
- Add license info to file

* Add basic ResourceManager, use in video_player.py

* Revert tagstudio.spec changes

* Change tuple usage to dicts

* Move ResourceManager initialization steps

* Fix errant list notation
2024-06-12 23:20:17 -07:00
Travis Abendshien
37ff35fcf6 Set mouse event transparency on ItemThumbs (#279) 2024-06-12 02:00:16 -07:00
Xarvex
9b13e338bb Use bug report and feature request forms for issues (#277)
* Initial bug report

* Images can be attached in description

* Enclose label in quotes

* Wikis are no longer being used

* Use footnote to clarify what is up-to-date

* Footnotes not supported in checklist

* Initial feature request form

* Fixup grammar/wording
2024-06-11 19:32:18 -07:00
Travis Abendshien
a47b0adb6e Update icon.ico 2024-06-11 17:29:30 -07:00
Travis Abendshien
9f39bf6fdc Update README: Correct version number in figure 2024-06-11 01:27:21 -07:00
Andrew Arneson
e375166bfe Raise error if video file has 0 frames or is in valid. (#275)
video.get(cv2.CAP_PROP_FRAME_COUNT) returns 0 or -1
2024-06-10 18:10:57 -07:00
Sean Krueger
7054ffd227 Separately pin QT nixpkg version (#244)
* Add missing libraries for video player

* Pin qt6 package version to 6.6.3

Currently, this succesfully launches the program. Pinning qt seperatly
allows the rest of unstable nixpkgs to be updated even after the qt
package version has been bumped. This fixes vim failing to launch in the
nix shell because of a bad gcc version. Bumping the package version to
qt6.7.1 also will require bumping PySide to 6.7.1, otherwise it will
fail to find qt. Qt 6.7.1 nixpkg commit is 47da0aee5616a063015f10ea593688646f2377e4

* fixup: Pin Qtcreator also

QtCreator was still against nixpkgs not the specific qt variant.
2024-06-10 14:52:13 -07:00
Travis Abendshien
6d283d1f2d Add CONTRIBUTING.md, update README 2024-06-10 02:30:16 -07:00
Travis Abendshien
a0baf015db Bump version to v9.3.1 Pre-Release 2024-06-08 15:34:29 -07:00
311 changed files with 25334 additions and 25008 deletions

16
.envrc.recommended Normal file
View File

@@ -0,0 +1,16 @@
# vi: ft=bash
#
# If you wish to use this file, copy or symlink it to `.envrc` for direnv to read it.
# This will use the flake development shell.
if ! has nix_direnv_version || ! nix_direnv_version 3.0.5; then
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.5/direnvrc" "sha256-RuwIS+QKFj/T9M2TFXScjBsLR6V3A17YVoEW/Q6AZ1w="
fi
devenv_root_file="$(mktemp -t devenv-root-XXXXXXXX)"
printf %s "${PWD}" >"${devenv_root_file}"
if ! use flake . --override-input devenv-root "file+file://${devenv_root_file}"; then
printf '%s\n' "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2
fi
rm "${devenv_root_file}"
unset devenv_root_file

7
.git-blame-ignore-revs Normal file
View File

@@ -0,0 +1,7 @@
# Date: Fri, 3 May 2024 19:40:36 -0700
# Reformatted using Ruff
089c8dd50cbf22e75721ecd2c0e0acfd3deca7f3
# Date: Fri, 13 Sep 2024 00:28:00 -0700
# ci(ruff)!: update ruff linter config, refactor to comply
b6e216760557c5507b12f210e1e48c531f49ffa3

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
patreon: cyanvoxel

64
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,64 @@
name: Bug Report
description: File a bug or issue report.
title: '[Bug]: '
labels: ['Type: Bug']
body:
- type: markdown
attributes:
value: |
*Please add an appropriate title for this issue.*
Before reporting, read the [documentation](https://github.com/TagStudioDev/TagStudio/blob/main/docs/index.md) and search existing [issues](https://github.com/TagStudioDev/TagStudio/issues).
Validate that you are using an up-to-date version[^1], your issue might already be fixed!
Questions, guidance, and usage goes in [discussions](https://github.com/TagStudioDev/TagStudio/discussions). Invalid issues will be closed.
[^1]: This can mean latest release, pre-release, or git commit.
- type: checkboxes
attributes:
label: Checklist
description: Make sure you've checked (and actually did) all of the below.
options:
- label: I am using an up-to-date version.
required: true
- label: I have read the [documentation](https://github.com/TagStudioDev/TagStudio/blob/main/docs/index.md).
required: true
- label: I have searched existing [issues](https://github.com/TagStudioDev/TagStudio/issues).
required: true
- type: input
attributes:
label: TagStudio Version
placeholder: Alpha 9.1.0
validations:
required: true
- type: input
attributes:
label: Operating System & Version
placeholder: TagOS 3.14
validations:
required: true
- type: textarea
attributes:
label: Description
description: Clear and concise description of the problem. Attach screenshots if needed, and include any errors you see.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: Clear and concise description of what you think should happen.
validations:
required: true
- type: textarea
attributes:
label: Steps to Reproduce
description: Minimal steps neded for the problem to occur.
placeholder: |
1.
2.
3.
validations:
required: true
- type: textarea
attributes:
label: Logs
description: Provide any logs, if applicable.

View File

@@ -0,0 +1,40 @@
name: Feature Request
description: Suggest a new feature.
title: '[Feature Request]: '
labels: ['Type: Enhancement']
body:
- type: markdown
attributes:
value: |
*Please add an appropriate title for this feature request.*
Before suggesting, read the [documentation](https://github.com/TagStudioDev/TagStudio/blob/main/docs/index.md) and search existing [issues](https://github.com/TagStudioDev/TagStudio/issues).
Validate that you are using an up-to-date version[^1], your feature might already be implemented!
Questions, guidance, and usage goes in [discussions](https://github.com/TagStudioDev/TagStudio/discussions). Invalid issues will be closed.
[^1]: This can mean latest release, pre-release, or git commit.
- type: checkboxes
attributes:
label: Checklist
description: Make sure you've checked (and actually did) all of the below.
options:
- label: I am using an up-to-date version.
required: true
- label: I have read the [documentation](https://github.com/TagStudioDev/TagStudio/blob/main/docs/index.md).
required: true
- label: I have searched existing [issues](https://github.com/TagStudioDev/TagStudio/issues).
required: true
- type: textarea
attributes:
label: Description
description: Clear and concise description of the problem or missing capability. Attach screenshots if needed, and explain your own use case.
validations:
required: true
- type: textarea
attributes:
label: Solution
description: Clear and concise description of what you think should happen.
- type: textarea
attributes:
label: Alternatives
description: Any considered alternative solutions or workarounds. If undesirable, why?

30
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,30 @@
### Summary
<!--
^^^ Summarize the changes done and why they were done above.
By submitting this pull request, you certify that you have read the
[CONTRIBUTING.md](https://github.com/TagStudioDev/TagStudio/blob/main/CONTRIBUTING.md).
IMPORTANT FOR FEATURES: Please verify that a feature request or some other form
of communication with maintainers was already conducted in terms of approving.
Thank you for your eagerness to contribute!
-->
### Tasks Completed
<!-- No requirements, just context for reviewers. -->
- Platforms Tested:
- [ ] Windows x86
- [ ] Windows ARM
- [ ] macOS x86
- [ ] macOS ARM
- [ ] Linux x86
- [ ] Linux ARM
<!-- If an unspecified platform was tested, please add it here -->
- Tested For:
- [ ] Basic functionality
- [ ] PyInstaller executable <!-- Not necessarily required, but appreciated! -->
<!-- If other important criteria was tested for, please add it here -->

View File

@@ -1,51 +0,0 @@
name: PySide App Test
on: [ push, pull_request ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install system dependencies
run: |
# dont run update, it is slow
# sudo apt-get update
sudo apt-get install -y --no-install-recommends \
libxkbcommon-x11-0 \
x11-utils \
libyaml-dev \
libegl1-mesa \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-randr0 \
libxcb-render-util0 \
libxcb-xinerama0 \
libopengl0 \
libxcb-cursor0 \
libpulse0
- name: Install dependencies
run: |
pip install -Ur requirements.txt
- name: Run TagStudio app and check exit code
run: |
xvfb-run --server-args="-screen 0, 1920x1200x24 -ac +extension GLX +render -noreset" python tagstudio/tag_studio.py --ci -o /tmp/
exit_code=$?
if [ $exit_code -eq 0 ]; then
echo "TagStudio ran successfully"
else
echo "TagStudio failed with exit code $exit_code"
exit 1
fi

View File

@@ -23,10 +23,9 @@ jobs:
- name: Install dependencies
run: |
# pyside 6.6.3 has some issue in their .pyi files
pip install PySide6==6.6.2
pip install -r requirements.txt
pip install mypy==1.10.0
python -m pip install --upgrade uv
uv pip install --system -r requirements.txt
uv pip install --system mypy==1.11.2
mkdir tagstudio/.mypy_cache
- uses: tsuyoshicho/action-mypy@v4

38
.github/workflows/publish_docs.yaml vendored Normal file
View File

@@ -0,0 +1,38 @@
name: Publish Docs
on:
push:
branches:
- main
paths:
- 'docs/**'
- 'mkdocs.yml'
- 'CHANGELOG.md'
- '.github/workflows/publish_docs.yaml'
permissions:
contents: write
concurrency:
group: publish-docs
cancel-in-progress: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: 3.x
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- uses: actions/cache@v4
with:
key: mkdocs-material-${{ env.cache_id }}
path: .cache
restore-keys: |
mkdocs-material-
- run: pip install mkdocs-material mkdocs-material[imaging]
- run: mkdocs gh-deploy --force

75
.github/workflows/pytest.yaml vendored Normal file
View File

@@ -0,0 +1,75 @@
name: pytest
on: [ push, pull_request ]
jobs:
pytest:
name: Run tests
runs-on: ubuntu-24.04
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install system dependencies
run: |
# dont run update, it is slow
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
libxkbcommon-x11-0 \
x11-utils \
libyaml-dev \
libgl1 \
libegl1 \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-randr0 \
libxcb-render-util0 \
libxcb-xinerama0 \
libopengl0 \
libxcb-cursor0 \
libpulse0
- name: Install dependencies
run: |
python -m pip install --upgrade uv
uv pip install --system -r requirements.txt
uv pip install --system -r requirements-dev.txt
- name: Run pytest
run: |
xvfb-run pytest --cov-report xml --cov=tagstudio
- name: Store coverage
uses: actions/upload-artifact@v4
with:
name: 'coverage'
path: 'coverage.xml'
coverage:
name: Check Code Coverage
runs-on: ubuntu-latest
needs: pytest
steps:
- name: Load coverage
uses: actions/download-artifact@v4
with:
name: 'coverage'
- name: Check Code Coverage
uses: yedpodtrzitko/coverage@main
with:
thresholdAll: 0.4
thresholdNew: 0.4
thresholdModified: 0.4
coverageFile: coverage.xml
token: ${{ secrets.GITHUB_TOKEN }}
sourceDir: tagstudio/src

View File

@@ -35,9 +35,9 @@ jobs:
macos:
strategy:
matrix:
os-version: ['12', '14']
os-version: ['13', '14']
include:
- os-version: '12'
- os-version: '13'
arch: x86_64
- os-version: '14'
arch: aarch64

View File

@@ -1,11 +1,20 @@
name: Ruff
on: [ push, pull_request ]
jobs:
ruff:
ruff-format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: chartboost/ruff-action@v1
with:
version: 0.4.2
version: 0.6.4
args: 'format --check'
ruff-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: chartboost/ruff-action@v1
with:
version: 0.6.4
args: 'check'

33
.gitignore vendored
View File

@@ -88,9 +88,7 @@ profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
@@ -140,6 +138,9 @@ venv.bak/
# Rope project settings
.ropeproject
# macoS
*.DS_Store
# mkdocs documentation
/site
@@ -162,7 +163,7 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.idea/
### Python Patch ###
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
@@ -174,6 +175,10 @@ poetry.toml
# LSP config files
pyrightconfig.json
# Syncthing
.stfolder/
.stignore
### Qt ###
# C++ objects and libs
*.slo
@@ -231,11 +236,11 @@ compile_commands.json
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# !.vscode/settings.json
# !.vscode/tasks.json
# !.vscode/launch.json
# !.vscode/extensions.json
# !.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
@@ -247,8 +252,16 @@ compile_commands.json
# Ignore all local history of files
.history
.ionide
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,python,qt
# TagStudio
.TagStudio
!*/tests/**/.TagStudio
tagstudio/tests/fixtures/library/*
tagstudio/tests/fixtures/json_library/.TagStudio/*.sqlite
TagStudio.ini
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,python,qt
*.sqlite-journal
.envrc
.direnv
.devenv

View File

@@ -1,6 +1,7 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.4.2
rev: v0.6.4
hooks:
- id: ruff-format
- id: ruff

17
.vscode/launch.json vendored
View File

@@ -1,17 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "TagStudio",
"type": "python",
"request": "launch",
"program": "${workspaceRoot}/tagstudio/tag_studio.py",
"console": "integratedTerminal",
"justMyCode": true,
"args": []
}
]
}

206
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,206 @@
# Contributing to TagStudio
_Last Updated: January 30th, 2025_
Thank you so much for showing interest in contributing to TagStudio! Here are a set of instructions and guidelines for contributing code or documentation to the project. This document will change over time, so make sure that your contributions still line up with the requirements here before submitting a pull request.
## Getting Started
- Check the [Feature Roadmap](/docs/updates/roadmap.md) page to see what priority features there are, the [FAQ](/README.md/#faq), as well as the open [Issues](https://github.com/TagStudioDev/TagStudio/issues) and [Pull Requests](https://github.com/TagStudioDev/TagStudio/pulls).
- If you'd like to add a feature that isn't on the feature roadmap or doesn't have an open issue, **PLEASE create a feature request** issue for it discussing your intentions so any feedback or important information can be given by the team first.
- We don't want you wasting time developing a feature or making a change that can't/won't be added for any reason ranging from pre-existing refactors to design philosophy differences.
- **Please don't** create pull requests that consist of large refactors, _especially_ without discussing them with us first. These end up doing more harm than good for the project by continuously delaying progress and disrupting everyone else's work.
- If you wish to discuss TagStudio further, feel free to join the [Discord Server](https://discord.com/invite/hRNnVKhF2G)
### Contribution Checklist
- I've read the [Feature Roadmap](/docs/updates/roadmap.md) page
- I've read the [FAQ](/README.md/#faq), including the "[Features I Likely Won't Add/Pull](/README.md/#features-i-likely-wont-addpull)" section
- I've checked the open [Issues](https://github.com/TagStudioDev/TagStudio/issues) and [Pull Requests](https://github.com/TagStudioDev/TagStudio/pulls)
- **I've created a new issue for my feature/fix _before_ starting work on it**, or have at least notified others in the relevant existing issue(s) of my intention to work on it
- I've set up my development environment including Ruff, Mypy, and PyTest
- I've read the [Code Guidelines](#code-guidelines) and/or [Documentation Guidelines](#documentation-guidelines)
- **_I mean it, I've found or created an issue for my feature/fix!_**
> [!NOTE]
> If the fix is small and self-explanatory (i.e. a typo), then it doesn't require an issue to be opened first. Issue tracking is supposed to make our lives easier, not harder. Please use your best judgement to minimize the amount of work involved for everyone involved.
## Creating a Development Environment
### Prerequisites
- [Python](https://www.python.org/downloads/) 3.12
- [Ruff](https://github.com/astral-sh/ruff) (Included in `requirements-dev.txt`)
- [Mypy](https://github.com/python/mypy) (Included in `requirements-dev.txt`)
- [PyTest](https://docs.pytest.org) (Included in `requirements-dev.txt`)
### Creating a Python Virtual Environment
If you wish to launch the source version of TagStudio outside of your IDE:
> [!IMPORTANT]
> Depending on your system, Python may be called `python`, `py`, `python3`, or `py3`. These instructions use the alias `python3` for consistency. You can check to see which alias your system uses and if it's for the correct Python version by typing `python3 --version` (or whichever alias) into your terminal.
> [!TIP]
> On Linux and macOS, you can launch the `tagstudio.sh` script to skip the following process, minus the `requirements-dev.txt` installation step. _Using the script is fine if you just want to launch the program from source._
1. Make sure you're using the correct Python version:
- If the output matches `Python 3.12.x` (where the x is any number) then you're using the correct Python version and can skip to step 2. Otherwise, you can install the correct Python version from the [Python](https://www.python.org/downloads/) website, or you can use a tool like [pyenv](https://github.com/pyenv/pyenv/) to install the correct version without changes to your system:
1. Follow pyenv's [install instructions](https://github.com/pyenv/pyenv/?tab=readme-ov-file#installation) for your system.
2. Install the appropriate Python version with pyenv by running `pyenv install 3.12` (This will **not** mess with your existing Python installation).
3. Navigate to the repository root folder in your terminal and run `pyenv local 3.12`.
- You could alternatively use `pyenv shell 3.12` or `pyenv global 3.12` instead to set the Python version for the current terminal session or the entire system respectively, however using `local` is recommended.
2. In the root repository directory, create a python virtual environment:
`python3 -m venv .venv`
3. Activate your environment:
- Windows w/Powershell: `.venv\Scripts\Activate.ps1`
- Windows w/Command Prompt: `.venv\Scripts\activate.bat`
- Linux/macOS: `source .venv/bin/activate`
Depending on your system, the regular activation script *might* not work on alternative shells. In this case, refer to the table below for supported shells:
|Shell |Script |
|-------:|:------------------------|
|Bash/ZSH|`.venv/bin/activate` |
|Fish |`.venv/bin/activate.fish`|
|CSH/TCSH|`.venv/bin/activate.csh` |
|PWSH |`.venv/bin/activate.ps1` |
4. Install the required packages:
- `pip install -r requirements.txt`
- If developing (includes Ruff and Mypy): `pip install -r requirements-dev.txt`
_Learn more about setting up a virtual environment [here](https://docs.python.org/3/tutorial/venv.html)._
### Manually Launching (Outside of an IDE)
If you encounter errors about the Python version, or seemingly vague script errors, [pyenv](https://github.com/pyenv/pyenv/) may solve your issue. See step 1 of [Creating a Python Virtual Environment](#creating-a-python-virtual-environment).
- **Windows** (start_win.bat)
- To launch TagStudio, launch the `start_win.bat` file. You can modify this .bat file or create a shortcut and add one or more additional arguments if desired.
- **Linux/macOS** (TagStudio.sh)
- Run the "TagStudio.sh" script and the program should launch! (Make sure that the script is marked as executable if on Linux). Note that launching from the script from outside of a terminal will not launch a terminal window with any debug or crash information. If you wish to see this information, just launch the shell script directly from your terminal with `./TagStudio.sh`.
- **NixOS** (Nix Flake)
- Use the provided [Flake](https://nixos.wiki/wiki/Flakes) to create and enter a working environment by running `nix develop`. Then, run the program via `python3 tagstudio/tag_studio.py` from the root directory.
> [!WARNING]
> Support for NixOS is still a work in progress.
- **Any** (No Scripts)
- Alternatively, with the virtual environment loaded, run the python file at `tagstudio\tag_studio.py` from your terminal. If you're in the project's root directory, simply run `python3 tagstudio/tag_studio.py`.
## Workflow Checks
When pushing your code, several automated workflows will check it against predefined tests and style checks. It's _highly recommended_ that you run these checks locally beforehand to avoid having to fight back-and-forth with the workflow checks inside your pull requests.
> [!TIP]
> To format the code automatically before each commit, there's a configured action available for the `pre-commit` hook. Install it by running `pre-commit install`. The hook will be executed each time on running `git commit`.
### [Ruff](https://github.com/astral-sh/ruff)
A Python linter and code formatter. Ruff uses the `pyproject.toml` as its config file and runs whenever code is pushed or pulled into the project.
#### Running Locally
Inside the root repository directory:
- Lint code with `ruff check`
- Some linting suggestions can be automatically formatted with `ruff check --fix`
- Format code with `ruff format`
Ruff should automatically discover the configuration options inside the [pyproject.toml](https://github.com/TagStudioDev/TagStudio/blob/main/pyproject.toml) file. For more information, see the [ruff configuration discovery docs](https://docs.astral.sh/ruff/configuration/#config-file-discovery).
Ruff is also available as a VS Code [extension](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff), PyCharm [plugin](https://plugins.jetbrains.com/plugin/20574-ruff), and [more](https://docs.astral.sh/ruff/integrations/).
### [Mypy](https://github.com/python/mypy)
Mypy is a static type checker for Python. It sure has a lot to say sometimes, but we recommend you take its advice when possible. Mypy also uses the `pyproject.toml` as its config file and runs whenever code is pushed or pulled into the project.
#### Running Locally
- **First time only:** Move into the `/tagstudio` directory with `cd tagstudio` and run the following:
- `mkdir -p .mypy_cache`
- `mypy --install-types --non-interactive`
- Check code by moving into the `/tagstudio` directory with `cd tagstudio` _(if you aren't already inside)_ and running `mypy --config-file ../pyproject.toml .`. _(Don't forget the `.` at the end!)_
Mypy is also available as a VS Code [extension](https://marketplace.visualstudio.com/items?itemName=matangover.mypy), PyCharm [plugin](https://plugins.jetbrains.com/plugin/11086-mypy), and [more](https://plugins.jetbrains.com/plugin/11086-mypy).
### PyTest
- Run all tests by moving into the `/tagstudio` directory with `cd tagstudio` and running `pytest tests/`.
## Code Style
Most of the style guidelines can be checked, fixed, and enforced via Ruff. Older code may not be adhering to all of these guidelines, in which case _"do as I say, not as I do"..._
- Do your best to write clear, concise, and modular code.
- Keep a maximum column with of no more than **100** characters.
- Code comments should be used to help describe sections of code that can't speak for themselves.
- Use [Google style](https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings) docstrings for any classes and functions you add.
- If you're modifying an existing function that does _not_ have docstrings, you don't _have_ to add docstrings to it... but it would be pretty cool if you did ;)
- Imports should be ordered alphabetically.
- Lists of values should be ordered using their [natural sort order](https://en.wikipedia.org/wiki/Natural_sort_order).
- Some files have their methods ordered alphabetically as well (i.e. [`thumb_renderer`](https://github.com/TagStudioDev/TagStudio/blob/main/tagstudio/src/qt/widgets/thumb_renderer.py)). If you're working in a file and notice this, please try and keep to the pattern.
- When writing text for window titles or form titles, use "[Title Case](https://apastyle.apa.org/style-grammar-guidelines/capitalization/title-case)" capitalization. Your IDE may have a command to format this for you automatically, although some may incorrectly capitalize short prepositions. In a pinch you can use a website such as [capitalizemytitle.com](https://capitalizemytitle.com/) to check.
- If it wasn't mentioned above, then stick to [**PEP-8**](https://peps.python.org/pep-0008/)!
### Modules & Implementations
- **Do not** modify legacy library code in the `src/core/library/json/` directory
- Avoid direct calls to `os`
- Use `Pathlib` library instead of `os.path`
- Use `platform.system()` instead of `os.name` and `sys.platform`
- Don't prepend local imports with `tagstudio`, stick to `src`
- Use the `logger` system instead of `print` statements
- Avoid nested f-strings
- Use HTML-like tags inside Qt widgets over stylesheets where possible
### Commit and Pull Request Style
- Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0) as a guideline for commit messages. This allows us to easily generate changelogs for releases.
- See some [examples](https://www.conventionalcommits.org/en/v1.0.0/#examples) of what this looks like in practice.
- Use clear and concise commit messages. If your commit does too much, either consider breaking it up into smaller commits or providing extra detail in the commit description.
- Pull requests should have an adequate title and description which clearly outline your intentions and changes/additions. Feel free to provide screenshots, GIFs, or videos, especially for UI changes.
- Pull requests should ideally be limited to **a single** feature or fix.
> [!IMPORTANT]
> Please do not force push if your PR is open for review!
>
> Force pushing makes it impossible to discern which changes have already been reviewed and which haven't. This means a reviewer will then have to rereview all the already reviewed code, which is a lot of unnecessary work for reviewers.
> [!TIP]
> If you're unsure where to stop the scope of your PR, ask yourself: _"If I broke this up, could any parts of it still be used by the project in the meantime?"_
### Runtime Requirements
- Final code must function on supported versions of Windows, macOS, and Linux:
- Windows: 10, 11
- macOS: 12.0+
- Linux: _Varies_
- Final code must **_NOT:_**
- Contain superfluous or unnecessary logging statements
- Cause unreasonable slowdowns to the program outside of a progress-indicated task
- Cause undesirable visual glitches or artifacts on screen
## Documentation Guidelines
Documentation contributions include anything inside of the `docs/` folder, as well as the `README.md` and `CONTRIBUTING.md` files. Documentation inside the `docs/` folder is built and hosted on our static documentation site, [docs.tagstud.io](https://docs.tagstud.io/).
- Use "[snake_case](https://developer.mozilla.org/en-US/docs/Glossary/Snake_case)" for file and folder names
- Follow the folder structure pattern
- Don't add images or other media with excessively large file sizes
- Provide alt text for all embedded media
- Use "[Title Case](https://apastyle.apa.org/style-grammar-guidelines/capitalization/title-case)" for title capitalization
## Translation Guidelines
Translations are performed on the TagStudio [Weblate project](https://hosted.weblate.org/projects/tagstudio/).
_Translation guidelines coming soon._

324
README.md
View File

@@ -1,71 +1,124 @@
# TagStudio (Alpha): A User-Focused Document Management System
# TagStudio: A User-Focused Document Management System
[![Translation](https://hosted.weblate.org/widget/tagstudio/strings/svg-badge.svg)](https://hosted.weblate.org/projects/tagstudio/strings/)
[![PyTest](https://github.com/TagStudioDev/TagStudio/actions/workflows/pytest.yaml/badge.svg)](https://github.com/TagStudioDev/TagStudio/actions/workflows/pytest.yaml)
[![MyPy](https://github.com/TagStudioDev/TagStudio/actions/workflows/mypy.yaml/badge.svg)](https://github.com/TagStudioDev/TagStudio/actions/workflows/mypy.yaml)
[![Ruff](https://github.com/TagStudioDev/TagStudio/actions/workflows/ruff.yaml/badge.svg)](https://github.com/TagStudioDev/TagStudio/actions/workflows/ruff.yaml)
[![Downloads](https://img.shields.io/github/downloads/TagStudioDev/TagStudio/total.svg?maxAge=2592001)](https://github.com/TagStudioDev/TagStudio/releases)
<p align="center">
<img width="60%" src="github_header.png">
<img width="60%" src="docs/assets/github_header.png">
</p>
> [!CAUTION]
> This is still a **_very_** rough personal project of mine in its infancy. Im open-sourcing it now in order to accept contributors sooner and to better facilitate the direction of the project from an earlier stage.
> There **_are_** bugs, and there will **_very likely_** be breaking changes!
TagStudio is a photo & file organization application with an underlying tag-based system that focuses on giving freedom and flexibility to the user. No proprietary programs or formats, no sea of sidecar files, and no complete upheaval of your filesystem structure. **Read the documentation and more at [docs.tagstud.io](https://docs.tagstud.io)!**
TagStudio is a photo & file organization application with an underlying system that focuses on giving freedom and flexibility to the user. No proprietary programs or formats, no sea of sidecar files, and no complete upheaval of your filesystem structure.
> [!NOTE]
> Thank you for being patient as we've migrated our database backend from JSON to SQL! The previous warnings about the main branch being experimental and unsupported have now been removed, and any pre-existing library save files created with official TagStudio releases are able to be opened and migrated with the new v9.5+ releases!
> [!IMPORTANT]
> This project is still in an early state. There are many missing optimizations and QoL features, as well as the presence of general quirks and occasional jankiness. Making frequent backups of your library save data is **always** important, regardless of what state the program is in.
>
> With this in mind, TagStudio will _NOT:_
>
> - Touch, move, or mess with your files in any way _(unless explicitly using the "Delete File(s)" feature, which is locked behind a confirmation dialog)_.
> - Ask you to recreate your tags or libraries after new releases. It's our highest priority to ensure that your data safely and smoothly transfers over to newer versions.
> - Cause you to suddenly be able to recall your 10 trillion downloaded images that you probably haven't even seen firsthand before. You're in control here, and even tools out there that use machine learning still needed to be verified by human eyes before being deemed accurate.
<p align="center">
<img width="80%" src="screenshot.jpg">
<img width="80%" src="docs/assets/screenshot.png" alt="TagStudio Screenshot">
</p>
<p align="center">
<i>TagStudio Alpha v9.5.0 running on macOS Sequoia.</i>
</p>
## Contents
- [Goals](#goals)
- [Priorities](#priorities)
- [Current Features](#current-features)
- [Installation](#installation)
- [Usage](#usage)
- [FAQ](#faq)
- [Goals](#goals)
- [Priorities](#priorities)
- [Current Features](#current-features)
- [Contributing](#contributing)
- [Installation](#installation)
- [Usage](#usage)
- [FAQ](#faq)
## Goals
- To achieve a portable, privacy-oriented, open, extensible, and feature-rich system of organizing and rediscovering files.
- To provide powerful methods for organization, notably the concept of tag composition, or “taggable tags”.
- To create an implementation of such a system that is resilient against a users actions outside the program (modifying, moving, or renaming files) while also not burdening the user with mandatory sidecar files or otherwise requiring them to change their existing file structures and workflows.
- To support a wide range of users spanning across different platforms, multi-user setups, and those with large (several terabyte) libraries.
- To make the darn thing look like nice, too. Its 2024, not 1994.
- To achieve a portable, private, extensible, open-format, and feature-rich system of organizing and rediscovering files.
- To provide powerful methods for organization, notably the concept of tag inheritance, or “taggable tags” _(and in the near future, the combination of composition-based tags)._
- To create an implementation of such a system that is resilient against a users actions outside the program (modifying, moving, or renaming files) while also not burdening the user with mandatory sidecar files or requiring them to change their existing file structures and workflows.
- To support a wide range of users spanning across different platforms, multi-user setups, and those with large (several terabyte) libraries.
- To make the dang thing look nice, too. Its 2025, not 1995.
## Priorities
1. **The concept.** Even if TagStudio as a project or application fails, Id hope that the idea lives on in a superior project. The [goals](#goals) outlined above dont reference TagStudio once - _TagStudio_ is what references the _goals._
1. **The concept.** Even if TagStudio as an application fails, Id hope that the idea lives on in a superior project. The [goals](#goals) outlined above dont reference TagStudio once - _TagStudio_ is what references the _goals._
2. **The system.** Frontends and implementations can vary, as they should. The core underlying metadata management system is what should be interoperable between different frontends, programs, and operating systems. A standard implementation for this should settle as development continues. This opens up the doors for improved and varied clients, integration with third-party applications, and more.
3. **The application.** If nothing else, TagStudio the application serves as the first (and so far only) implementation for this system of metadata management. This has the responsibility of doing the idea justice and showing just whats possible when it comes to user file management.
4. (The name.) I think its fine for an app or client, but it doesnt really make sense for a system or standard. I suppose this will evolve with time.
4. (The name.) I think its fine for an app or client, but it doesnt really make sense for a system or standard. I suppose this will evolve with time...
## Contributing
If you're interested in contributing to TagStudio, please take a look at the [contribution guidelines](/CONTRIBUTING.md) for how to get started!
Translation hosting generously provided by [Weblate](https://weblate.org/en/). Check out our [project page](https://hosted.weblate.org/projects/tagstudio/) to help translate TagStudio!
## Current Features
- Create libraries/vaults centered around a system directory. Libraries contain a series of entries: the representations of your files combined with metadata fields. Each entry represents a file in your librarys directory, and is linked to its location.
- Add metadata to your library entries, including:
- Name, Author, Artist (Single-Line Text Fields)
- Description, Notes (Multiline Text Fields)
- Tags, Meta Tags, Content Tags (Tag Boxes)
- Create rich tags composed of a name, a list of aliases, and a list of “subtags” - being tags in which these tags inherit values from.
- Search for entries based on tags, ~~metadata~~ (TBA), or filenames/filetypes (using `filename: <query>`)
- Special search conditions for entries that are: `untagged`/`no tags` and `empty`/`no fields`.
### Libraries
- Create libraries/vaults centered around a system directory. Libraries contain a series of entries: the representations of your files combined with metadata fields. Each entry represents a file in your librarys directory, and is linked to its location.
- Address moved, deleted, or otherwise "unlinked" files by using the "Fix Unlinked Entries" option in the Tools menu.
### Tagging + Custom Metadata
- Add custom powerful tags to your library entries
- Add metadata to your library entries, including:
- Name, Author, Artist (Single-Line Text Fields)
- Description, Notes (Multiline Text Fields)
- Create rich tags composed of a name, color, a list of aliases, and a list of “parent tags” - these being tags in which these tags inherit values from.
- Copy and paste tags and fields across file entries
- Automatically organize tags into groups based on parent tags marked as "categories"
- Generate tags from your existing folder structure with the "Folders to Tags" macro (NOTE: these tags do NOT sync with folders after they are created)
### Search
- Search for file entries based on tags, file path (`path:`), file types (`filetype:`), and even media types! (`mediatype:`). Path searches currently use [glob](<https://en.wikipedia.org/wiki/Glob_(programming)>) syntax, so you may need to wrap your filename or filepath in asterisks while searching. This will not be strictly necessary in future versions of the program.
- Use and combine boolean operators (`AND`, `OR`, `NOT`) along with parentheses groups, quotation escaping, and underscore substitution to create detailed search queries
- Use special search conditions (`special:untagged` and `special:empty`) to find file entries without tags or fields, respectively
### File Entries
- Nearly all file types are supported in TagStudio libraries - just not all have dedicated thumbnail support.
- Preview most image file types, animated GIFs, videos, plain text documents, audio files, Blender projects, and more!
- Open files or file locations by right-clicking on thumbnails and previews and selecting the respective context menu options. You can also click on the preview panel image to open the file, and click the file path label to open its location.
- Delete files from both your library and drive by right-clicking the thumbnail(s) and selecting the "Move to Trash"/"Move to Recycle Bin" option.
> [!NOTE]
> For more information on the project itself, please see the [FAQ](#faq) section and other docs.
> For more information on the project itself, please see the [FAQ](#faq) section as well as the [documentation](https://docs.tagstud.io/)!
## Installation
To download TagStudio, visit the [Releases](https://github.com/TagStudioDev/TagStudio/releases) section of the GitHub repository and download the latest release for your system. TagStudio is available for **Windows**, **macOS** _(Apple Silicon & Intel)_, and **Linux**. Windows and Linux builds are also available in portable versions if you want a more self-contained executable to move around.
To download TagStudio, visit the [Releases](https://github.com/TagStudioDev/TagStudio/releases) section of the GitHub repository and download the latest release for your system under the "Assets" section. TagStudio is available for **Windows**, **macOS** _(Apple Silicon & Intel)_, and **Linux**. Windows and Linux builds are also available in portable versions if you want a more self-contained executable to move around.
> [!NOTE]
**We do not currently publish TagStudio to any package managers. Any TagStudio distributions outside of the GitHub releases page are _unofficial_ and not maintained by us.** Installation support will not be given to users installing from unofficial sources. Use these versions at your own risk.
> [!IMPORTANT]
> On macOS, you may be met with a message saying _""TagStudio" can't be opened because Apple cannot check it for malicious software."_ If you encounter this, then you'll need to go to the "Settings" app, navigate to "Privacy & Security", and scroll down to a section that says _""TagStudio" was blocked from use because it is not from an identified developer."_ Click the "Open Anyway" button to allow TagStudio to run. You should only have to do this once after downloading the application.
#### Optional Arguments
> [!IMPORTANT]
> On Linux with non-Qt based Desktop Environments you may be unable to open TagStudio. You need to make sure that "xcb-cursor0" or "libxcb-cursor0" packages are installed. For more info check [Missing linux dependencies](https://github.com/TagStudioDev/TagStudio/discussions/182#discussioncomment-9452896)
Optional arguments to pass to the program.
### Third-Party Dependencies
- For video thumbnails and playback, you'll also need [FFmpeg](https://ffmpeg.org/download.html) installed on your system. If you encounter any issues with this, please reference our [FFmpeg Help](/docs/help/ffmpeg.md) guide.
### Optional Arguments
Arguments available to pass to the program, either via the command line or a shortcut.
> `--open <path>` / `-o <path>`
> Path to a TagStudio Library folder to open on start.
>
> `--config-file <path>` / `-c <path>`
> Path to the TagStudio config file to load.
@@ -77,14 +130,19 @@ With TagStudio opened, start by creating a new library or opening an existing on
### Refreshing the Library
In order to scan for new files or file changes, youll need to manually go to File -> Refresh Directories.
Libraries under 10,000 files automatically scan for new or modified files when opened. In order to refresh the library manually, select "Refresh Directories" under the File menu.
> [!NOTE]
> In the future, library refreshing will also be automatically done in the background, or additionally on app startup.
### Adding Tags to File Entries
### Adding Metadata to Entries
Access the "Add Tag" search box by either clicking on the "Add Tag" button at the bottom of the right sidebar, accessing the "Add Tags to Selected" option from the File menu, or by pressing <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>T</kbd>.
To add a metadata field to a file entry, start by clicking the “Add Field” button under the file preview in the right-hand preview panel. From the dropdown menu, select the type of metadata field youd like to add to the entry.
From here you can search for existing tags or create a new one if the one you're looking for doesn't exist. Click the “+” button next to any tags you want to to the currently selected file entries. To quickly add the top result, press the <kbd>Enter</kbd>/<kbd>Return</kbd> key to add the the topmost tag and reset the tag search. Press <kbd>Enter</kbd>/<kbd>Return</kbd> once more to close the dialog box. By using this method, you can quickly add various tags in quick succession just by using the keyboard!
To remove a tag from a file entry, hover over the tag in the preview panel and click on the "-" icon that appears.
### Adding Metadata to File Entries
To add a metadata field to a file entry, start by clicking the “Add Field” button at the bottom of the preview panel. From the dropdown menu, select the type of metadata field youd like to add to the entry
### Editing Metadata Fields
@@ -92,45 +150,48 @@ To add a metadata field to a file entry, start by clicking the “Add Field” b
Hover over the field and click the pencil icon. From there, add or edit text in the dialog box popup.
#### Tag Box
Click the “+” button at the end of the Tags list, and search for tags to add inside the new dialog popup. Click the “+” button next to whichever tags you want to add. Alternatively, after you search for a tag, press the Enter/Return key to add the add the first item in the list. Press Enter/Return once more to close the dialog box
> [!WARNING]
> Keyboard control and navigation is currently _very_ buggy, but will be improved in future versions.
### Creating Tags
To create a new tag, click on Edit -> New Tag from the menu bar. From there, enter a tag name, shorthand name, any tag aliases separated by newlines, any subtags, and an optional color.
Create a new tag by accessing the "New Tag" option from the Edit menu or by pressing <kbd>Ctrl</kbd>+<kbd>T</kbd>. In the tag creation panel, enter a tag name, optional shorthand name, optional tag aliases, optional parent tags, and an optional color.
- The tag **shorthand** is a type of alias that displays in situations when screen space is more valuable (ex. as a subtag for other tags).
- **Aliases** are alternate names for a tag. These let you search for terms other than the exact tag name in order to find the tag again.
- **Subtags** are tags in which this tag is a child tag of. In other words, tags under this section are parents of this tag. For example, if you had a tag for a character from a show, you would make the show a subtag of this character. This would display as “Character (Show)” in most areas of the app. The first tag in this list is used as the tag shown in parentheses for specification.
- The **color** dropdown lets you select an optional color for this tag to display as.
- The tag **name** is the base name of the tag. **_This does NOT have to be unique!_**
- The tag **shorthand** is a special type of alias that displays in situations where screen space is more valuable, notably with name disambiguation.
- **Aliases** are alternate names for a tag. These let you search for terms other than the exact tag name in order to find the tag again.
- **Parent Tags** are tags in which this this tag can substitute for in searches. In other words, tags under this section are parents of this tag.
- Parent tags with the disambiguation check next to them will be used to help disambiguate tag names that may not be unique.
- For example: If you had a tag for "Freddy Fazbear", you might add "Five Nights at Freddy's" as one of the parent tags. If the disambiguation box is checked next to "Five Nights at Freddy's" parent tag, then the tag "Freddy Fazbear" will display as "Freddy Fazbear (Five Nights at Freddy's)". Furthermore, if the "Five Nights at Freddy's" tag has a shorthand like "FNAF", then the "Freddy Fazbear" tag will display as "Freddy Fazbear (FNAF)".
- The **color** option lets you select an optional color palette to use for your tag.
- The **"Is Category"** property lets you treat this tag as a category under which itself and any child tags inheriting from it will be sorted by inside the preview panel.
#### Tag Manager
You can manage your library of tags from opening the "Tag Manager" panel from Edit -> "Tag Manager". From here you can create, search for, edit, and permanently delete any tags you've created in your library.
### Editing Tags
To edit a tag, right-click the tag in the tag field of the preview pane and select “Edit Tag”
To edit a tag, click on it inside the preview panel or right-click the tag and select “Edit Tag” from the context menu.
### Relinking Moved Files
Inevitably some of the files inside your library will be renamed, moved, or deleted. If a file has been renamed or moved, TagStudio will display the thumbnail as a red broken chain link. To relink moved files or delete these entries, select the "Manage Unlinked Entries" option under the Tools menu. Click the "Refresh" button to scan your library for unlinked entries. Once complete, you can attempt to “Search & Relink” any unlinked file entries to their respective files, or “Delete Unlinked Entries” in the event the original files have been deleted and you no longer wish to keep their entries inside your library.
> [!WARNING]
> There is currently no method to view all tags that youve created in your library. This is a top priority for future releases.
### Relinking Renamed/Moved Files
Inevitably, some of the files inside your library will be renamed, moved, or deleted. If a file has been renamed or moved, TagStudio will display the thumbnail as a red tag with a cross through it _(this icon is also used for items with broken thumbnails)._ To relink moved files or delete these entries, go to Tools -> Manage Unlinked Entries. Click the “Refresh” button to scan your library for unlinked entries. Once complete, you can attempt to “Search & Relink” any unlinked entries to their respective files, or “Delete Unlinked Entries” in the event the original files have been deleted and you no longer wish to keep their metadata entries inside your library.
> There is currently no method to relink entries to files that have been renamed - only moved or deleted. This is a high priority for future releases.
> [!WARNING]
> There is currently no method to relink entries to files that have been renamed - only moved or deleted. This is a top priority for future releases.
> [!WARNING]
> If multiple matches for a moved file are found (matches are currently defined as files with a matching filename as the original), TagStudio will currently ignore the match groups. Adding a GUI for manual selection, as well as smarter automated relinking, are top priorities for future versions.
> If multiple matches for a moved file are found (matches are currently defined as files with a matching filename as the original), TagStudio will currently ignore the match groups. Adding a GUI for manual selection, as well as smarter automated relinking, are high priorities for future versions.
### Saving the Library
Libraries are saved upon exiting the program. To manually save, select File -> Save Library from the menu bar. To save a backup of your library, select File -> Save Library Backup from the menu bar.
As of version 9.5, libraries are saved automatically as you go. To save a backup of your library, select File -> Save Library Backup from the menu bar.
### Half-Implemented Features
These features were present in pre-public versions of TagStudio (9.0 and below) and have yet to be fully implemented.
#### Fix Duplicate Files
Load in a .dupeguru file generated by [dupeGuru](https://github.com/arsenetar/dupeguru/) and mirror metadata across entries marked as duplicates. After mirroring, return to dupeGuru to manage deletion of the duplicate files. After deletion, use the “Fix Unlinked Entries” feature in TagStudio to delete the duplicate set of entries for the now-deleted files
@@ -138,13 +199,6 @@ Load in a .dupeguru file generated by [dupeGuru](https://github.com/arsenetar/du
> [!CAUTION]
> While this feature is functional, its a pretty roundabout process and can be streamlined in the future.
#### Image Collage
Create an image collage of your photos and videos.
> [!CAUTION]
> Collage sizes and options are hardcoded.
#### Macros
Apply tags and other metadata automatically depending on certain criteria. Set specific macros to run when the files are added to the library. Part of this includes applying tags automatically based on parent folders.
@@ -159,142 +213,28 @@ Import JSON sidecar data generated by [gallery-dl](https://github.com/mikf/galle
> [!CAUTION]
> This feature is not supported or documented in any official capacity whatsoever. It will likely be rolled-in to a larger and more generalized sidecar importing feature in the future.
## Creating a Development Environment
## Launching/Building From Source
If you're interested in contributing to TagStudio or just wish to poke around the live codebase, here are instructions for setting up the Python project.
### Prerequisites
- Python 3.12
### Creating a Python Virtual Environment
> [!NOTE]
> Depending on your system, Python may be called `python`, `py`, `python3`, or `py3`. These instructions use the alias `python3`. You can check to see which alias you system uses and if it's for the correct Python version by typing `python3 --version` (or whichever alias) into your terminal.
_Skip these steps if launching from the .sh script on Linux/macOS._
1. In the root repository directory, create a python virtual environment:
`python3 -m venv .venv`
2. Activate your environment:
- Windows w/Powershell: `.venv\Scripts\Activate.ps1`
- Windows w/Command Prompt: `.venv\Scripts\activate.bat`
- Linux/macOS: `source .venv/bin/activate`
3. Install the required packages:
- required to run the app: `pip install -r requirements.txt`
- required to develop: `pip install -r requirements-dev.txt`
To run all the tests use `python -m pytest tests/` from the `tagstudio` folder.
_Learn more about setting up a virtual environment [here](https://docs.python.org/3/tutorial/venv.html)._
### Launching Development Environment
- **Windows** (start_win.bat)
- To launch TagStudio, launch the `start_win.bat` file. You can modify this .bat file or create a shortcut and add one or more additional arguments if desired.
- **Linux/macOS** (TagStudio.sh)
- Run the "TagStudio.sh" script, and the program should launch! (Make sure that the script is marked as executable if on Linux). Note that launching from the script from outside of a terminal will not launch a terminal window with any debug or crash information. If you wish to see this information, just launch the shell script directly from your terminal with `./TagStudio.sh`.
- **NixOS** (TagStudio.sh)
- Use the provided `flake.nix` file to create and enter a working environment by running `nix develop`. Then, run the `TagStudio.sh` script.
- **Any** (No Scripts)
- Alternatively, with the virtual environment loaded, run the python file at `tagstudio\tag_studio.py` from your terminal. If you're in the project's root directory, simply run `python3 tagstudio/tag_studio.py`.
See instructions in the "[Creating Development Environment](/CONTRIBUTING.md/#creating-a-development-environment)" section from the [contribution documentation](/CONTRIBUTING.md).
## FAQ
### What State Is the Project Currently In?
As of writing (Alpha v9.2.1) the project is in a useable state, however it lacks proper testing and quality of life features.
As of writing (Alpha v9.5.0) the project is very usable, however there's some plenty of quirks and missing QoL features. Several additional features and changes are still planned (see: [Feature Roadmap](https://docs.tagstud.io/updates/roadmap/)) that add even more power and flexibility to the tagging and field systems while making it easier to tag in bulk and perform automated operations. Bugfixes and polish are constantly trickling in along with the larger feature releases.
### What Features Are You Planning on Adding?
> [!NOTE]
> **_See [Planned Features](/doc/planned_features.md) documentation._**
See the [Feature Roadmap](https://docs.tagstud.io/updates/roadmap/) page for the core features being planned and implemented for TagStudio. For a more up to date look on what's currently being added for upcoming releases, see our GitHub [milestones](https://github.com/TagStudioDev/TagStudio/milestones) for versioned releases.
Of the several features I have planned for the project, these are broken up into “priority” features and “future” features. Priority features were originally intended for the first public release, however are currently absent from the Alpha v9.x.x builds.
### Features That Will NOT Be Added
#### Priority Features
- Native Cloud Integration
- There are plenty of services already (native or third-party) that allow you to mount your cloud drives as virtual drives on your system. Hosting a TagStudio library on one of these mounts should function similarly to what native integration would look like.
- Supporting native cloud integrations such as these would be an unnecessary "reinventing the wheel" burden for us that is outside the scope of this project.
- Native ChatGPT/Non-Local LLM Integration
- This could mean different things depending on your intentions. Whether it's trying to use an LLM to replace the native search, or to trying to use a model for image recognition, I'm not interested in hooking people's TagStudio libraries into non-local LLMs such as ChatGPT and/or turn the program into a "chatbot" interface (see: [Goals/Privacy](#goals)). I wouldn't, however, mind using **locally** hosted models to provide the _optional_ ability for additional searching and tagging methods (especially when it comes to facial recognition) - but this would likely take the form of plugins external to the core program anyway.
- Improved search
- Sortable Search
- Boolean Search
- Coexisting Text + Tag Search
- Searchable File Metadata
- Comprehensive Tag management tab
- Easier ways to apply tags in bulk
- Tag Search Panel
- Recent Tags Panel
- Top Tags Panel
- Pinned Tags Panel
- Better (stable, performant) library grid view
- Improved entry relinking
- Cached thumbnails
- Tag-like Groups
- Resizable thumbnail grid
- User-defined metadata fields
- Multiple directory support
- SQLite (or similar) save files
- Reading of EXIF and XMP fields
- Improved UI/UX
- Better internal API for accessing Entries, Tags, Fields, etc. from the library.
- Proper testing workflow
- Continued code cleanup and modularization
- Exportable/importable library data including "Tag Packs"
### Why Is this Already Version 9?
#### Future Features
- Support for multiple simultaneous users/clients
- Draggable files outside the program
- Comprehensive filetype whitelist
- A finished “macro system” for automatic tagging based on predetermined criteria.
- Different library views
- Date and time fields
- Entry linking/referencing
- Audio waveform previews
- 3D object previews
- Additional previews for miscellaneous file types
- Optional global tags and settings, spanning across libraries
- Importing & exporting libraries to/from other programs
- Port to a more performant language and modern frontend (Rust?, Tauri?, etc.)
- Plugin system
- Local OCR search
- Support for local machine learning-based tag suggestions for images
- Mobile version _(FAR future)_
#### Features I Likely Wont Add/Pull
- Native Cloud Integration
- There are plenty of services already (native or third-party) that allow you to mount your cloud drives as virtual drives on your system. Pointing TagStudio to one of these mounts should function similarly to what native integration would look like.
- Native ChatGPT/Non-Local LLM Integration
- This could mean different things depending on what you're intending. Whether it's trying to use an LLM to replace the native search, or to trying to use a model for image recognition, I'm not interested in hooking people's TagStudio libraries into non-local LLMs such as ChatGPT and/or turn the program into a "chatbot" interface (see: [Goals/Privacy](#goals)). I wouldn't, however, mind using **locally** hosted models to provide the _optional_ ability for additional searching and tagging methods (especially when it comes to facial recognition).
### Why Is the Version Already v9?
Ive been developing this project over several years in private, and have gone through several major iterations and rewrites in that time. This “major version” is just a number at the end of the day, and if I wanted to I couldnt released this as “Version 0” or “Version 1.0”, but Ive decided to stick to my original version numbers to avoid needing to go in and change existing documentation and code comments. Version 10 is intended to include all of the “Priority Features” Ive outlined in the [previous](#what-features-are-you-planning-on-adding) section. Ive also labeled this version as an Alpha, and will likely reset the numbers when a feature-complete beta is reached.
### Wait, Is There a CLI Version?
As of right now, **no**. However, I _did_ have a CLI version in the recent past before dedicating my efforts to the Qt GUI version. Ive left in the currently-inoperable CLI code just in case anyone was curious about it. Also yes, its just a bunch of glorified print statements (_the outlook for some form of curses on Windows didnt look great at the time, and I just needed a driver for the newly refactored code...)._
### Can I Contribute?
**Yes!!** I recommend taking a look at the [Priority Features](#priority-features), [Future Features](#future-features), and [Features I Won't Pull](#features-i-likely-wont-addpull) lists, as well as the project issues to see whats currently being worked on. Please do not submit pull requests with new feature additions without opening up an issue with a feature request first.
Code formatting is automatically checked via [Ruff](https://docs.astral.sh/ruff/).
To format the code manually, install ruff via `pip install -r requirements-dev.txt` and then run `ruff format`
To format the code automatically before each commit, there's a configured action available for `pre-commit` hook. Install it by running `pre-commit install`. The hook will be executed each time on running `git commit`.
More structured documentation on contribution requirements is on its way, but for now:
- Use `pathlib` in favor of `os.path`
- Try to make new UI additions match the existing style of the application
Over the first few years of private development the project went through several major iterations and rewrites. These major version bumps came quickly, and by the time TagStudio was opened-sourced the version number had already reached v9.0. Instead of resetting to "v0.0" or "v1.0" for this public release I decided to keep my v9.x numbering scheme and reserve v10.0 for when all the core features on the [Feature Roadmap](https://docs.tagstud.io/updates/roadmap/) are implemented. Ive also labeled this version as an "Alpha" and will drop this once either all of the core features are implemented or the project feels stable and feature-rich enough to be considered "Beta" and beyond.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

View File

@@ -1,24 +0,0 @@
# Welcome to the TagStudio Documentation!
> [!WARNING]
> This documentation is still a work in progress, and is intended to aide with deconstructing and understanding of the core mechanics of TagStudio and how it operates.
<div align="center">
<img src="../github_header.png" alt="TagStudio Alpha" height="100">
<img src="https://i0.wp.com/www.bapl.org/wp-content/uploads/2019/02/old-under-construction-gif.gif" alt="Under Construction" height="100">
</div>
## Table of Contents
- [Library](/doc/library/library.md)
- [Entries](/doc/library/entry.md)
- [Fields](/doc/library/field.md)
- [Tags](/doc/library/tag.md)
- [Tools & Macros](/doc/utilities/macro.md)
- [Planned Features](/doc/updates/planned_features.md)
---
### [Database Migration](/doc/updates/db_migration.md)
The "Database Migration", "DB Migration", or "SQLite Migration" is an upcoming update to TagStudio which will replace the current JSON [library](/doc/library/library.md) with a SQL-based one, and will additionally include some fundamental changes to how some features such as [tags](/doc/library/tag.md) will work.

View File

@@ -1,25 +0,0 @@
# Entry
Entries are the units that fill a [library](/doc/library/library.md). Each one corresponds to a file, holding a reference to it along with the metadata associated with it.
### Entry Object Structure
1. `id`:
- Int, Unique, **Required**
- The ID for the Entry.
- Used for internal processing
2. `filename`:
- String, **Required**
- The filename with extension of the referenced media file.
3. `path`:
- String, **Required**, OS Agnostic
- The folder path in which the media file is located in.
4. [`fields`](/doc/library/field.md):
- List of dicts, Optional
- A list of Field ID/Value dicts.
NOTE: _Entries currently have several unused optional fields intended for later features._
## Retrieving Entries based on [Tag](/doc/library/tag.md) Cluster
By default when querying Entries, each Entry's `tags` list (stored in the form of Tag `id`s) is compared against the Tag `id`s in a given Tag cluster (list of Tag `id`s) or appended clusters in the case of multi-term queries. The type of comparison depends on the type of query and whether or not it is an inclusive or exclusive query, or a combination of both. This default searching behavior is done in _O(n)_ time, but can be sped up in the future by building indexes on certain search terms. These indexes can be stored on disk and loaded back into memory in future sessions. These indexes will also need to be updated as new Tags and Entries are added or edited.

View File

@@ -1,34 +0,0 @@
# Field
Fields are the building blocks of metadata stored in [entries](/doc/library/entry.md). Fields have several base types for representing different kinds of information, including:
#### `text_line`
- A string of text, displayed as a single line.
- e.g: Title, Author, Artist, URL, etc.
#### `text_box`
- A long string of text displayed as a box of text.
- e.g: Description, Notes, etc.
#### `tag_box`
- A box of [tags](/doc/library/tag.md) defined and added by the user.
- Multiple tag boxes can be used to separate classifications of tags.
- e.g: Content Tags, Meta Tags, etc.
#### `datetime` [WIP]
- A date and time value.
- e.g: Date Created, Date Modified, Date Taken, etc.
#### `checkbox` [WIP]
- A simple two-state checkbox.
- Can be associated with a tag for quick organization.
- e.g: Archive, Favorite, etc.
#### `collation` [obsolete]
- Previously used for associating files to be used in a [collation](/doc/utilities/macro.md#create-collage), will be removed in favor of a more flexible feature in future updates.

View File

@@ -1,11 +0,0 @@
# Library
The library is how TagStudio represents your chosen directory, with every file inside of it being displayed as an [entry](/doc/library/entry.md). You can have as many or few libraries as you wish, since each libraries' data is stored within a "`.TagStudio`" folder at its root.
Note that this means [tags](/doc/library/tag.md) you create only exist _per-library_.
### Library Contents
- [Entries](/doc/library/entry.md)
- [Fields](/doc/library/field.md)
- [Tags](/doc/library/tag.md)
- [Macros](/doc/utilities/macro.md)

View File

@@ -1,85 +0,0 @@
# Tag
Tags are user-defined attributes made up of one or more keywords, aliases, and relationships to other tags. A person, place, thing, concept, you name it! Tags allow for a more sophisticated way to organize and search [entries](/doc/library/entry.md) thanks to their aliases, parent tags, and more.
Tags can be as simple or complex as wanted, so that any user can tune TagStudio to fit their needs.
Among the things that make tags so useful, aliases give the ability to contain alternate names and spellings, making searches intuitive and expansive. Furthermore, parent-tags/subtags offer relational organization capabilities for the structuring and connection of the [library's](/doc/library/library.md) contents.
## Tag Object Structure
#### `id`
ID for the tag.
- Int, Unique, Required
- Used for internal processing
#### `name`
The normal name of the tag, with no shortening or specification.
- String, Required
- Doesn't have to be unique
- Used for display, searching, and storing
#### `shorthand`
The shorthand name for the tag. Works like an alias but is used for specific display purposes.
- String, Optional
- Doesn't have to be unique
- Used for display and searching
#### `aliases`
Alternate names for the tag.
- List of Strings, Optional
- Recommended to be unique to this tag
- Used for searching
#### `subtags`
Other Tags that make up properties of this tag. Also called "parent tags".
- List of Strings, Optional
- Used for display (first parent tag only) and searching.
#### `color`
A color name string for customizing the tag's display color
- String, Optional
- Used for display
## Tag Search Examples:
Using for example, a library of files including some tagged with the following tags:
| Tag | `name` | `shorthand` | `aliases` | `parent tags` |
| ------------------- | ------------------- | ----------- | ---------------------- | -------------------------------------------- |
| _League of Legends_ | "League of Legends" | "LoL" | ["League"] | ["Game", "Fantasy"] |
| _Arcane_ | "Arcane" | "" | [] | ["League of Legends", "Cartoon"] |
| _Jinx (LoL)_ | "Jinx Piltover" | "Jinx" | ["Jinxy", "Jinxy Poo"] | ["League of Legends", "Arcane", "Character"] |
| _Zander (Arcane)_ | "Zander Zanderson" | "Zander" | [] | ["Arcane", "Character"] |
| _Mr. Legend (LoL)_ | "Mr. Legend" | "" | [] | ["League of Legends", "Character"] |
**The query "Arcane" will display results tagged with:**
| Tag | Cause of Inclusion | Tag Tree Lineage |
| --------------- | -------------------------------- | -------------------------- |
| Arcane | Direct match of tag name | "Arcane" |
| Jinx (LoL) | Search term is set as parent tag | "Jinx (LoL) > Arcane" |
| Zander (Arcane) | Search term is set as parent tag | "Zander (Arcane) > Arcane" |
**The query "League of Legends" will display results tagged with:**
| Tag | Cause of Inclusion | Tag Tree Lineage |
| ----------------- | ------------------------------------------------------ | ---------------------------------------------- |
| League of Legends | Direct match of tag name | "League of Legends" |
| Arcane | Search term is set as parent tag | "Arcane > League of Legends" |
| Jinx (LoL) | Search term is set as parent tag | "Jinx (LoL) > League of Legends" |
| Mr. Legend (LoL) | Search term is set as parent tag | "Mr. Legend (LoL) > League of Legends" |
| Zander (Arcane) | Search term is a parent tag of a tag set as parent tag | "Zander (Arcane) > Arcane > League of Legends" |
Note: The query "LoL" will display the same results as the above example since "LoL" is the shorthand for "League of Legends".

View File

@@ -1,3 +0,0 @@
# Tag Categories (Upcoming Feature)
Replaces [Tag Fields](/doc/library/field.md#tag_box). Tags are able to be marked as a “category” which then displays as tag fields currently do, with any tags inheriting from that category being displayed underneath.

View File

@@ -1,16 +0,0 @@
# Tag Overrides (Upcoming Feature)
Tag overrides are the ability to add or remove [parent tags](/doc/library/tag.md#subtags) from a [tag](/doc/library/tag.md) on a per- [entry](/doc/library/entry.md) basis. Relies on the [Database Migration](/doc/updates/db_migration.md) update being complete.
## Examples
<figure>
<img src="../assets/tag_override_ex-1.png" alt="Example 1" height="300">
<figcaption>Ex. 1 - Comparing standard tag composition vs additive and subtractive inheritance overrides.</figcaption>
</figure>
<figure>
<img src="../assets/tag_override_ex-2.png" alt="Example 2" height="300">
<figcaption>Ex. 2 - Parent tag swap using tag overrides.</figcaption>
</figure>

View File

@@ -1,43 +0,0 @@
# Database Migration
The database migration is an upcoming refactor to TagStudio's library data storage system. The database will be migrated from a JSON-based one to a SQLite-based one. Part of this migration will include a reworked schema, which will allow for several new features and changes to how [tags](/doc/library/tag.md) and [fields](/doc/library/field.md) operate.
## Schema
<img src="../assets/db_schema.png" alt="Database Schema" width="500">
### `alias` Table
_Description TBA_
### `entry` Table
_Description TBA_
### `entry_attribute` Table
_Description TBA_
### `entry_page` Table
_Description TBA_
### `location` Table
_Description TBA_
### `tag` Table
_Description TBA_
### `tag_relation` Table
_Description TBA_
## Resulting New Features and Changes
- Multiple Directory Support
- [Tag Categories](/doc/library/tag_categories.md) (Replaces [Tag Fields](/doc/library/field.md#tag_box))
- [Tag Overrides](/doc/library/tag_overrides.md)
- User-Defined [Fields](/doc/library/field.md)
- Tag Icons

View File

@@ -1,59 +0,0 @@
# Planned Features
The following lists outline the planned major and minor features for TagStudio, in no particular order.
# Major Features
- [SQL Database Migration](/doc/updates/db_migration.md)
- Multiple Directory Support
- [Tags Categories](/doc/library/tag_categories.md)
- [Entry Groups](/doc/library/entry_groups.md)
- [Tag Overrides](/doc/library/tag_overrides.md)
- Tagging Panel
- Top Tags
- Recent Tags
- Tag Search
- Pinned Tags
- Configurable Default Fields (May be part of [Macros](/doc/utilities/macro.md))
- Deep File Extension Control
- Settings Menu
- Custom User Colors
- Search Engine Rework
- Boolean Search
- Tag Objects In Search
- Search For Fields
- Sortable Search Results
- Automatic Entry Relinking
- Detect Renames
- Detect Moves
- Thumbnail Caching
- User-Defined Fields
- Exportable Library/Tag Data
- Exportable Human-Readable Library
- Exportable/Importable Human-Readable “Tag Packs”
- Exportable/Importable Color Palettes
- Configurable Thumbnail Labels
- Toggle Extension Label
- Toggle File Size Label
- Configurable Thumbnail Tag Badges
- Customize tags that appear instead of just “Archive” and “Favorite”
- OCR Search
## Minor Features
- Deleting Tags
- Merging Tags
- Tag Icons
- Tag/Field Copy + Paste
- Collage UI
- Resizable Thumbnail Grid
- Draggable Files Outside The Program
- File Property Caching
- 3D Previews
- Audio Waveform Previews
- Toggle Between Waveform And Album Artwork
- PDF Previews
- SVG Previews
- Full Video Player
- Duration Properties For Video + Audio Files
- Optional Starter Tag Packs

View File

@@ -1,43 +0,0 @@
# Tools & Macros
Tools and macros are features that serve to create a more fluid [library](/doc/library/library.md)-managing process, or provide some extra functionality. Please note that some are still in active development and will be fleshed out in future updates.
## Tools
### Fix Unlinked Entries
This tool displays the number of unlinked [entries](/doc/library/entry.md), and some options for their resolution.
1. Refresh
- Scans through the library and updates the unlinked entry count.
2. Search & Relink
- Attempts to automatically find and reassign missing files.
3. Delete Unlinked Entries
- Displays a confirmation prompt containing the list of all missing files to be deleted before committing to or cancelling the operation.
### Fix Duplicate Files
This tool allows for management of duplicate files in the library using a [DupeGuru](https://dupeguru.voltaicideas.net/) file.
1. Load DupeGuru File
- load the "results" file created from a DupeGuru scan
2. Mirror Entries
- Duplicate entries will have their contents mirrored across all instances. This allows for duplicate files to then be deleted with DupeGuru as desired, without losing the [field](/doc/library/field.md) data that has been assigned to either. (Once deleted, the "Fix Unlinked Entries" tool can be used to clean up the duplicates)
### Create Collage
This tool is a preview of an upcoming feature. When selected, TagStudio will generate a collage of all the contents in a Library, which can be found in the Library folder ("/your-folder/.TagStudio/collages/"). Note that this feature is still in early development, and doesn't yet offer any customization options.
## Macros
### Auto-fill [WIP]
Tool is in development and will be documented in future update.
### Sort fields
Tool is in development, will allow for user-defined sorting of [fields](/doc/library/field.md).
### Folders to Tags
Creates tags from the existing folder structure in the library, which are previewed in a hierarchy view for the user to confirm. A tag will be created for each folder and applied to all entries, with each subfolder being linked to the parent folder as a [parent tag](/doc/library/tag.md#subtags). Tags will initially be named after the folders, but can be fully edited and customized afterwards.

1
docs/CNAME Normal file
View File

@@ -0,0 +1 @@
docs.tagstud.io

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

BIN
docs/assets/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

BIN
docs/assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 KiB

BIN
docs/assets/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

54
docs/help/ffmpeg.md Normal file
View File

@@ -0,0 +1,54 @@
# FFmpeg
FFmpeg is required for thumbnail previews and playback features on audio and video files. FFmpeg is a free Open Source project dedicated to the handling of multimedia (video, audio, etc) files. For more information, see their official website at [ffmpeg.org](https://www.ffmpeg.org/).
## Installation on Windows
### Prebuilt Binaries
Pre-built binaries from trusted sources are available on the [FFmpeg website](https://www.ffmpeg.org/download.html). Under "More downloading options" click on the Windows section, then under "Windows EXE Files" select a source to download a build from. Follow any further download instructions from whichever build website you choose.
![Windows Download Location](../assets/ffmpeg_windows_download.png)
<!-- prettier-ignore -->
!!! warning
Do NOT download the source code by mistake!
To Install:
1. Download 7z or zip file and extract it (right click > Extract All)
2. Move extracted contents to a unique folder (i.e; `c:\ffmpeg` or `c:\Program Files\ffmpeg`)
3. Add FFmpeg to your system PATH
1. In Windows, search for or go to "Edit the system environment variables" under the Control Panel
2. Under "User Variables", select "Path" then edit
3. Click new and add `<Your folder>\bin` (e.g; `c:\ffmpeg\bin` or `c:\Program Files\ffmpeg\bin`)
4. Click "Okay"
### Package Managers
FFmpeg is also available from:
1. WinGet (`winget install ffmpeg`)
2. Scoop (`scoop install main/ffmpeg`)
3. Chocolatey (`choco install ffmpeg-full`)
## Installation on Mac
### Homebrew
FFmpeg is available under the macOS section of the [FFmpeg website](https://www.ffmpeg.org/download.html) or can be installed via [Homebrew](https://brew.sh/) using `brew install ffmpeg`.
## Installation on Linux
### Package Managers
FFmpeg may be installed by default on some Linux distributions, but if not, it is available via your distro's package manager of choice:
1. Debian/Ubuntu (`sudo apt install ffmpeg`)
2. Fedora (`sudo dnf install ffmpeg-free`)
3. Arch (`sudo pacman -S ffmpeg`)
# Help
For additional help, please join the [Discord](https://discord.gg/hRNnVKhF2G) or create an Issue on the [GitHub repository](https://github.com/TagStudioDev/TagStudio)

52
docs/index.md Normal file
View File

@@ -0,0 +1,52 @@
---
title: Home
---
# Welcome to the TagStudio Documentation!
![TagStudio Alpha](assets/github_header.png)
TagStudio is a photo & file organization application with an underlying tag-based system that focuses on giving freedom and flexibility to the user. No proprietary programs or formats, no sea of sidecar files, and no complete upheaval of your filesystem structure.
<figure width="60%" markdown="span">
![TagStudio screenshot](assets/screenshot.png)
<figcaption>TagStudio Alpha v9.5.0 running on macOS Sequoia.</figcaption>
</figure>
## Feature Roadmap
The [Feature Roadmap](updates/roadmap.md) lists all of the planned core features for TagStudio to be considered "feature complete" along with estimated release milestones. The development and testing of these features takes priority over all other requested or submitted features unless they are later added to this roadmap. This helps ensure that TagStudio eventually sees a full release and becomes more usable by more people more quickly.
## Current Features
### Libraries
- Create [libraries](./library/index.md) centered around a system directory. Libraries contain a series of entries: the representations of your files combined with metadata fields. Each entry represents a file in your librarys directory, and is linked to its location.
- Address moved, deleted, or otherwise "unlinked" files by using the "Fix Unlinked Entries" option in the Tools menu.
### Tagging + Metadata Fields
- Add custom powerful [tags](./library/tag.md) to your library entries
- Add [metadata fields](./library/field.md) to your library entries, including:
- Name, Author, Artist (Single-Line Text Fields)
- Description, Notes (Multiline Text Fields)
- Create rich tags composed of a name, color, a list of aliases, and a list of “parent tags” - these being tags in which these tags inherit values from.
- Copy and paste tags and fields across file entries
- Automatically organize tags into groups based on parent tags marked as "categories"
- Generate tags from your existing folder structure with the "Folders to Tags" macro (NOTE: these tags do NOT sync with folders after they are created)
### Search
- [Search](./library/library_search.md) for file entries based on tags, file path (`path:`), file types (`filetype:`), and even media types! (`mediatype:`)
- Use and combine boolean operators (`AND`, `OR`, `NOT`) along with parentheses groups, quotation escaping, and underscore substitution to create detailed search queries
- Use special search conditions (`special:untagged`) to find file entries without tags or fields, respectively
### File Entries
- Nearly all [file](./library/entry.md) types are supported in TagStudio libraries - just not all have dedicated thumbnail support.
- Preview most image file types, animated GIFs, videos, plain text documents, audio files, Blender projects, and more!
- Open files or file locations by right-clicking on thumbnails and previews and selecting the respective context menu options. You can also click on the preview panel image to open the file, and click the file path label to open its location.
- Delete files from both your library and drive by right-clicking the thumbnail(s) and selecting the "Move to Trash"/"Move to Recycle Bin" option.

27
docs/install.md Normal file
View File

@@ -0,0 +1,27 @@
# Installation
To download TagStudio, visit the [Releases](https://github.com/TagStudioDev/TagStudio/releases) section of the GitHub repository and download the latest release for your system under the "Assets" section. TagStudio is available for **Windows**, **macOS** _(Apple Silicon & Intel)_, and **Linux**. Windows and Linux builds are also available in portable versions if you want a more self-contained executable to move around.
**We do not currently publish TagStudio to any package managers. Any TagStudio distributions outside of the GitHub releases page are _unofficial_ and not maintained by us.** Installation support will not be given to users installing from unofficial sources. Use these versions at your own risk.
<!-- prettier-ignore -->
!!! info "For macOS Users"
On macOS, you may be met with a message saying _""TagStudio" can't be opened because Apple cannot check it for malicious software."_ If you encounter this, then you'll need to go to the "Settings" app, navigate to "Privacy & Security", and scroll down to a section that says _""TagStudio" was blocked from use because it is not from an identified developer."_ Click the "Open Anyway" button to allow TagStudio to run. You should only have to do this once after downloading the application.
<!-- prettier-ignore -->
!!! info "For Linux Users"
On Linux with non-Qt based Desktop Environments you may be unable to open TagStudio. You need to make sure that "xcb-cursor0" or "libxcb-cursor0" packages are installed. For more info check [Missing linux dependencies](https://github.com/TagStudioDev/TagStudio/discussions/182#discussioncomment-9452896)
## Third-Party Dependencies
- For video thumbnails and playback, you'll also need [FFmpeg](https://ffmpeg.org/download.html) installed on your system. If you encounter any issues with this, please reference our [FFmpeg Help](./help/ffmpeg.md) guide.
## Optional Arguments
Optional arguments to pass to the program:
`--open <path>` / `-o <path>`
: Path to a TagStudio Library folder to open on start.
`--config-file <path>` / `-c <path>`
: Path to the TagStudio config file to load.

50
docs/library/entry.md Normal file
View File

@@ -0,0 +1,50 @@
# File Entries
File entries are the individual representations of your files inside a TagStudio [library](index.md). Each one corresponds one-to-one to a file on disk, and tracks all of the additional [tags](tag.md) and metadata that you attach to it inside TagStudio.
## Storage
File entry data is storied within the `ts_library.sqlite` file inside each library's `.TagStudio` folder. No modifications are made to your actual files on disk, and nothing like sidecar files are generated for your files.
## Appearance
File entries appear as file previews both inside the thumbnail grid. The preview panel shows a more detailed preview of the file, along with extra file stats and all attached TagStudio tags and fields.
## Unlinked File Entries
If the file that an entry is referencing has been moved, renamed, or deleted on disk, then TagStudio will display a red chain-link icon for the thumbnail image. Certain uncached stats such as the file size and image dimensions will also be unavailable to see in the preview panel when a file becomes unlinked.
To fix file entries that have become unlinked, select the "Fix Unlinked Entries" option from the Tools menu. From there, refresh the unlinked entry count and choose whether to search and relink you files, and/or delete the file entires from your library. This will NOT delete or modify any files on disk.
## Internal Structure
- `id` (`INTEGER`/`int`, `UNIQUE`, `NOT NULL`, `PRIMARY KEY`)
- The ID for the file entry.
- Used for guaranteed unique references.
- `folder` (`INTEGER`/`int`, `NOT NULL`, `FOREIGN KEY`)
- _Not currently used, may be removed._
- `path` (`VARCHAR`/`Path`, `UNIQUE`, `NOT NULL`)
- The filename and filepath relative to the root of the library folder.
- (E.g. for library "Folder", path = "any_subfolders/filename.txt")
- `suffix` (`VARCHAR`/`str`, `NOT NULL`)
- The filename suffix with no leading dot.
- Used for quicker file extension checks.
- `date_created` (`DATETIME`/`Datetime`)
- _Not currently used, will be implemented in an upcoming update._
- The creation date of the file (not the entry).
- Generates from `st_birthtime` on Windows and Mac, and `st_ctime` on Linux.
- `date_modified` (`DATETIME`/`Datetime`)
- _Not currently used, will be implemented in an upcoming update._
- The latest modification date of the file (not the entry).
- Generates from `st_mtime`.
- `date_added` (`DATETIME`/`Datetime`)
- The date the file entry was added to the TagStudio library.
### Table Relationships
- `tag_entries`
- A relationship between `entry_id` to `tag_id`s from the `tags` table.
- `text_fields`
- (TODO: determine the relationship for `entry_id`)
- `datetime_fields`
- (TODO: determine the relationship for `entry_id`)

View File

@@ -1,3 +1,8 @@
# Entry Groups (Upcoming Feature)
---
tags:
- Upcoming Feature
---
# Entry Groups
Entries can be grouped via tags marked as “groups” which when applied to different entries will signal TagStudio to treat those entries as a single group inside of searches and browsing.

23
docs/library/field.md Normal file
View File

@@ -0,0 +1,23 @@
# Fields
Fields are additional types of metadata that you can attach to [file entries](entry.md). Like [tags](tag.md), fields are not stored inside files themselves nor in sidecar files, but rather inside the respective TagStudio [library](index.md) save file.
## Field Types
### Text Line
A string of text, displayed as a single line.
- e.g: Title, Author, Artist, URL, etc.
### Text Box
A long string of text displayed as a box of text.
- e.g: Description, Notes, etc.
### Datetime [WIP]
A date and time value.
- e.g: Date Published, Date Taken, etc.

5
docs/library/index.md Normal file
View File

@@ -0,0 +1,5 @@
# Library
The library is how TagStudio represents your chosen directory, with every file inside being represented by a [file entry](entry.md). You can have as many or few libraries as you wish, since each libraries' data is stored within a `.TagStudio` folder at its root. From there the library save file itself is stored as `ts_library.sqlite`, with TagStudio versions 9.4 and below using a the legacy `ts_library.json` format.
Note that this means [tags](tag.md) you create only exist _per-library_.

View File

@@ -0,0 +1,121 @@
# Library Search
TagStudio provides various methods to search your library, ranging from TagStudio data such as tags to inherent file data such as paths or media types.
## Boolean Operators
TagStudio allows you to use common [boolean search](https://en.wikipedia.org/wiki/Full-text_search#Boolean_queries) operators when searching your library, along with [grouping](#grouping-and-nesting), [nesting](#grouping-and-nesting), and [character escaping](#escaping-characters). Note that you may need to use grouping in order to get the desired results you're looking for.
### AND
The `AND` operator will only return results that match **both** sides of the operator. `AND` is used implicitly when no boolean operators are given. To use the `AND` operator explicitly, simply type "and" (case insensitive) in-between items of your search.
<!-- prettier-ignore -->
!!! example
Searching for "Tag1 Tag2" will be treated the same as "Tag1 `AND` Tag2" and will only return results that contain both Tag1 and Tag2.
### OR
The `OR` operator will return results that match **either** the left or right side of the operator. To use the `OR` operator simply type "or" (case insensitive) in-between items of your search.
<!-- prettier-ignore -->
!!! example
Searching for "Tag1 `OR` Tag2" will return results that contain either "Tag1", "Tag2", or both.
### NOT
The `NOT` operator will returns results where the condition on the right is **false.** To use the `NOT` operator simply type "not" (case insensitive) in-between items of your search. You can also begin your search with `NOT` to only view results that do not contain the next term that follows.
<!-- prettier-ignore -->
!!! example
Searching for "Tag1 `NOT` Tag2" will only return results that contain "Tag1" while also not containing "Tag2".
### Grouping and Nesting
Searches can be grouped and nested by using parentheses to surround parts of your search query.
<!-- prettier-ignore -->
!!! example
Searching for "(Tag1 `OR` Tag2) `AND` Tag3" will return results any results that contain Tag3, plus one or the other (or both) of Tag1 and Tag2.
### Escaping Characters
Sometimes search queries have ambiguous characters and need to be "escaped". This is most common with tag names which contain spaces, or overlap with existing search keywords such as "[path:](#filename-and-path) of exile". To escape most search terms, surround the section of your search in plain quotes. Alternatively, spaces in tag names can be replaced by underscores.
#### Valid Escaped Tag Searches
- "Tag Name With Spaces"
- Tag_Name_With_Spaces
#### Invalid Escaped Tag Searches
- Tag Name With Spaces
- Reason: Ambiguity between a tag named "Tag Name With Spaces" and four individual tags called "Tag", "Name", "With", "Spaces".
## Tags
[Tag](#tags) search is the default mode of file entry search in TagStudio. No keyword prefix is required, however using `tag:` will also work. The tag search attempts to match tag [names](tag.md#name), [shorthands](tag.md#shorthand), [aliases](tag.md#aliases), as well as allows for tags to [substitute](tag.md#intuition-via-substitution) in for any of their [parent tags](tag.md#parent-tags).
You may also see the `tag_id:` prefix keyword show up with using the right-click "Search for Tag" option on tags. This is meant for internal use, and eventually will not be displayed or accessible to the user.
## Fields
_[Field](field.md) search is currently not in the program, however is coming in a future version._
## File Entry Search
### Filename and Path
Filename and path search is available via the `path:` keyword and comes in a few different styles. By default, any string that follows the `path:` keyword will be searched as a substring inside a file's complete filepath. This means that given a file `folder/my_file.txt`, searching for `path: my_file` or `path: folder` will both return results for that file.
#### Case Sensitivity
TagStudio uses a "[smartcase](https://neovim.io/doc/user/options.html#'smartcase')"-like system for case sensitivity. This means that a search term typed in `lowercase` will be treated as **case-insensitive**, while a term typed in any `MixedCase` will be treated as **case-sensitive**. This makes it quicker to type searches when case sensitivity isn't required, while also providing a simple option to leverage case sensitivity when desired. Note that this means there's technically no way to currently search for a lowercase term while respecting case sensitivity.
#### Glob Syntax
Optionally, you may use [glob](<https://en.wikipedia.org/wiki/Glob_(programming)>) syntax to search filepaths.
#### Examples
Given a file "Artwork/Piece.jpg", the following searches will return results for it:
- `path: artwork/piece.jpg`
- `path: Artwork/Piece.jpg`
- `path: piece.jpg`
- `path: Piece.jpg`
- `path: artwork`
- `path: rtwor`
- `path: ece.jpg`
- `path: iec`
- `path: artwork/*`
- `path: Artwork/*`
- `path: *piece.jpg*`
- `path: *Piece.jpg*`
- `path: *artwork*`
- `path: *Artwork*`
- `path: *rtwor*`
- `path: *ece.jpg*`
- `path: *iec*`
- `path: *.jpg`
While the following searches will **NOT:**
- `path: ARTWORK/Piece.jpg` _(Reason: Mismatched case)_
- `path: *aRtWoRk/Piece*` _(Reason: Mismatched case)_
- `path: PieCe.jpg` _(Reason: Mismatched case)_
- `path: *PieCe.jpg*` _(Reason: Mismatched case)_
## Special Searches
Some predefined searches use the `special:` keyword prefix and give quick results for certain special search queries.
### Untagged
To see all your file entries which don't contain any tags, use the `special: untagged` search.
### Empty
**_NOTE:_** _Currently unavailable in v9.5.0_
To see all your file entries which don't contain any tags _and_ any fields, use the `special: empty` search.

131
docs/library/tag.md Normal file
View File

@@ -0,0 +1,131 @@
# Tags
Tags are discrete objects that represent some attribute. This could be a person, place, object, concept, and more. Unlike most tagging systems, TagStudio tags are not solely represented by a line of text or a hashtag. Tags in TagStudio consist of several properties and relationships that give extra customization, searching power, and ease of tagging that cannot be achieved by string-based tags alone. TagStudio tags are designed to be as simple or as complex as you'd like, giving options to users of all skill levels and use cases.
## Naming Tags
TagStudio tags do not share the same naming limitations of many other tagging solutions. The key standouts of tag names in TagStudio are:
- Tag names do **NOT** have to be unique
- Tag names are **NOT** limited to specific characters
- Tags can have **aliases**, a.k.a. alternate names to go by
### Name
This is the base name of a tag. It does not have to be unique, and can use any characters you wish. If your tag can go by multiple names, for example if it's the name of a person or something that's commonly shortened or abbreviated, then it's recommended that you put the full tag name here.
### Shorthand
This is a special type of alias that's used for shortening the tag name under special circumstances, mostly when screen space is limited. Tag shorthands can be searched for just like tag names and tag aliases.
### Aliases
Aliases are alternate names that the tag can go by. This may include individual first names for people, alternate spellings, shortened names, and more. If there's a common abbreviation or shortened name for your tag, it's recommended to use the [shorthand](#shorthand) field for this instead.
When searching for a tag, aliases (including the shorthand) can also be used to find the tag. This not only includes searching for tags themselves, but for tagged [file entries](entry.md) as well!
### Automatic Disambiguation
Just as in real life, sometimes there are different attributes that share the same name with one another. The process of adding specificity to something in order to not confuse it with something similar is known as [disambiguation](https://en.wikipedia.org/wiki/Word-sense_disambiguation). In TagStudio we give the option to automatically disambiguate tag names based on a specially marked [Parent Tag](#parent-tags). Parent tags are explained in further detail below, but for the purposes of tag names they can lend themselves to clarifying the name of a tag without the user needing to manually change the name or add complicated aliases.
Given a tag named "Freddy", we may confuse it with other "Freddy" tags in our library. There are lots of Freddys in the world, after all. If we're talking about Freddy from "Five Nights at Freddy's", then we may already (and likely should) have a separate "Five Nights at Freddy's" tag added as a parent tag. When the disambiguation box next to a parent tag is selected (see image below) then our tag name will automatically display its name with that parent tag's name (or shorthand if available) in parentheses.
![Tag Disambiguation Example](../assets/tag_disambiguation_example.png)
So if the "Five Night's at Freddy's" tag is added as a parent tag on the "Freddy" tag, and the disambiguation box next to it is checked, then our tag name will automatically be displayed as "Freddy (Five Nights at Freddy's)". Better yet, if the "Five Night's at Freddy's" tag has a shorthand such as "FNAF", then our "Freddy" tag will be displayed as "Freddy (FNAF)". This process preserves our base tag name ("Freddy") and provides an option to get a clean and consistent method to display disambiguating parent categories, rather than having to type this information in manually for each applicable tag.
## Tag Relationships
One of the core properties of tags in TagStudio is their ability to form relationships with other tags, just as attributes have relationships with each other in real life. A rectangle is a square, but a square isn't a rectangle. A certain plumber with a red hat and blue overalls might be part of a well-known media franchise, developed by an equally well-known company. But how do representing these relationships help with tagging images and files? With tag relationships, we can leverage the following principles:
1. [Simplicity via Deduplication](#simplicity-via-deduplication)
2. [Intuition via Substitution](#intuition-via-substitution)
3. [Rediscovery via Linking](#rediscovery-via-linking)
### Parent Tags
#### Simplicity via Deduplication
In a system where tags have no relationships, you're required to add as many tags as you possibly can to describe every last element of an image or file. If you want to tag an image of Shrek, you need to add a tag for `Shrek` himself, a `Character` tag since he's a character, a `Movie` and perhaps `Dreamworks` tag since he's a character from a movie, or perhaps a `Book` tag if we're talking about the original character, and then of course tags for every other attribute of Shrek shown or implied. By allowing tags to have inheritance relationships, we can have a single `Shrek` tag inherit from `Character` (Shrek IS a character) as well as from a separate `Shrek (Movie Franchise)` tag that itself inherits from `Movie Franchise` and `Dreamworks`. Now by simply adding the `Shrek` tag to an image, we've effectively also added the `Character`, `Shrek (Move Franchise)`, `Movie Franchise`, and `Dreamworks` attributes all in one go. On the image entry itself we only see `Shrek`, but the rest of the attributes are implied.
![Shrek Tag Details](../assets/built_tag_shrek.png)
#### Intuition via Substitution
Now when searching for for images that have `Dreamworks` and `Character`, any images or files originally just tagged with `Shrek` will appear as you would expect. A little bit of tag setup goes a long way not only saving so much time during tagging, but also to ensure an intuitive way to search your files!
#### Rediscovery via Linking
Lastly, when searching your files with broader categories such as `Character` or `Dreamworks` you may rediscover images and files that you had simply tagged with tags such as `Barbatus` or `Tulio`, since you didn't need to manually tag those files with `Character` or `Dreamworks`, but had forgotten that they are both in fact Dreamworks characters. While you focus on tagging your files with seemingly surface level attributes, your TagStudio library is building rich connections between tags and files that may not be fully apparent until being discovered through various search queries. While you were simply tagging images with `Shrek` and `Tulio`, you may have unlocked an easy way to search for "2D Dreamworks Characters" without having to explicitly tag for that!
### Component Tags
**_[Coming in version 9.6](../updates/roadmap.md#v96)_**
Component tags will be built from a composition-based, or "HAS" type relationship between tags. This takes care of instances where an attribute may "have" another attribute, but doesn't inherit from it. Shrek may be an `Orge`, he may be a `Character`, but he is NOT a `Leather Vest` - even if he's commonly seen _with_ it. Component tags, along with the upcoming [Tag Override](tag_overrides.md) feature, are built to handle these cases in a way that still simplifies the tagging process without adding too much undue complexity for the user.
## Tag Appearance
### Color
Tags use a default uncolored appearance by default, however can take on a number of built-in and user-created colors and color palettes! Tag color palettes can be based on a single color value (see: TagStudio Standard, TagStudio Shades, TagStudio Pastels) or use an optional secondary color use for the text and optionally the tag border (e.g. TagStudio Neon).
![Tag Color Selection](../assets/tag_color_selection.png)
#### User-Created Colors
Custom palettes and colors can be created via the [Tag Color Manager](./tag_color.md). These colors will display alongside the built-in colors inside the tag selection window and are separated by their namespace names. Colors which use the secondary color for the tag border will be outlined in that color, otherwise they will only display the secondary color on the bottom of the swatch to indicate at a glance that the text colors are different.
![Custom Tag Color Selection](../assets/custom_tag_color_selection.png)
### Icon
**_[Coming in version 9.6](../updates/roadmap.md#v96)_**
## Tag Properties
Properties are special attributes of tags that change their behavior in some way.
#### Is Category
When the "Is Category" property is checked, this tag now acts as a category separator inside the preview panel. If this tag or any tags inheriting from this tag (i.e. tags that have this tag as a "[Parent Tag](#parent-tags)"), then these tags will appear under a separated group that's named after this tag. Tags inheriting from multiple "category tags" will still show up under any applicable category. _Read more under: [Tag Categories](../library/tag_categories.md)._
![Tag Category Example](../assets/tag_categories_example.png)
#### Is Hidden
**_[Coming in version 9.6](../updates/roadmap.md#v96)_**
When the "Is Hidden" property is checked, any file entries tagged with this tag will not show up in searches by default. This property comes by default with the built-in "Archived" tag.
## Tag Search Examples
The following are examples of how a set of given tags will respond to various search queries.
| Tag | Name | Shorthand | Aliases | Parent Tags |
| ------------------- | ------------------- | --------- | ---------------------- | -------------------------------------------- |
| _League of Legends_ | "League of Legends" | "LoL" | ["League"] | ["Game", "Fantasy"] |
| _Arcane_ | "Arcane" | "" | [] | ["League of Legends", "Cartoon"] |
| _Jinx (LoL)_ | "Jinx Piltover" | "Jinx" | ["Jinxy", "Jinxy Poo"] | ["League of Legends", "Arcane", "Character"] |
| _Zander (Arcane)_ | "Zander Zanderson" | "Zander" | [] | ["Arcane", "Character"] |
| _Mr. Legend (LoL)_ | "Mr. Legend" | "" | [] | ["League of Legends", "Character"] |
**The query "Arcane" will display results tagged with:**
| Tag | Cause of Inclusion | Tag Tree Lineage |
| --------------- | -------------------------------- | -------------------------- |
| Arcane | Direct match of tag name | "Arcane" |
| Jinx (LoL) | Search term is set as parent tag | "Jinx (LoL) > Arcane" |
| Zander (Arcane) | Search term is set as parent tag | "Zander (Arcane) > Arcane" |
**The query "League of Legends" will display results tagged with:**
| Tag | Cause of Inclusion | Tag Tree Lineage |
| ----------------- | ------------------------------------------------------ | ---------------------------------------------- |
| League of Legends | Direct match of tag name | "League of Legends" |
| Arcane | Search term is set as parent tag | "Arcane > League of Legends" |
| Jinx (LoL) | Search term is set as parent tag | "Jinx (LoL) > League of Legends" |
| Mr. Legend (LoL) | Search term is set as parent tag | "Mr. Legend (LoL) > League of Legends" |
| Zander (Arcane) | Search term is a parent tag of a tag set as parent tag | "Zander (Arcane) > Arcane > League of Legends" |
Note: The query "LoL" will display the same results as the above example since "LoL" is the shorthand for "League of Legends".

View File

@@ -0,0 +1,17 @@
---
tags:
---
# Tag Categories
The "Is Category" property of tags determines if a tag should be treated as a category itself when being organized inside the preview panel. Tags marked as categories will show themselves and all tags inheriting from it (including recursively) underneath a field-like section with the tag's name. This means that duplicates of tags can appear on entries if the tag inherits from multiple parent categories, however this is by design and reflects the nature multiple inheritance. Any tags not inheriting from a category tag will simply show under a default "Tag" section.
![Tag Categories Example](../assets/tag_categories_example.png)
### Built-In Tags and Categories
The built-in tags "Favorite" and "Archived" inherit from the built-in "Meta Tags" category which is marked as a category by default. This behavior of default tags can be fully customized by disabling the category option and/or by adding/removing the tags' Parent Tags.
### Migrating from v9.4 Libraries
Due to the nature of how tags and Tag Felids operated prior to v9.5, the organization style of Tag Categories vs Tag Fields is not 1:1. Instead of tags being organized into fields on a per-entry basis, tags themselves determine their organizational layout via the "Is Property" flag. Any tags _(not currently inheriting from either the "Favorite" or "Archived" tags)_ will be shown under the default "Tags" header upon migrating to the v9.5+ library format. Similar organization to Tag Fields can be achieved by using the built-in "Meta Tags" tag or any other marked with "Is Category" and then setting those tags as parents for other tags to inherit from.

71
docs/library/tag_color.md Normal file
View File

@@ -0,0 +1,71 @@
# Tag Colors
TagStudio features a variety of built-in tag colors, alongside the ability for users to create their own custom tag color palettes.
## Tag Color Manager
The Tag Color Manager is where you can create and manage your custom tag colors and associated namespaces. To open the Tag Color Manager, go to "File -> Manage Tag Colors" option in the menu bar.
![Tag Color Manager](../assets/tag_color_manager.png)
## Creating a Namespace
TagStudio uses namespaces to group colors into palettes. Namespaces are a way for you to use the same color name across multiple palettes without having to worry about [name collision](https://en.wikipedia.org/wiki/Name_collision) with other palettes. This is especially useful when sharing your color palettes with others!\*
_\* Color pack sharing coming in a future update_
To create your first namespace, either click the "New Namespace" button or the large button prompt underneath the built-in colors.
![Create Namespace](../assets/create_namespace.png)
### Name
The display name of the namespace, used for presentation.
### ID Slug
An internal ID for the namespace which is automatically derived from the namespace name.
Namespaces beginning with "tagstudio" are reserved by TagStudio and will automatically have their text changed.
<!-- prettier-ignore -->
!!! note
It's currently not possible to manually edit the Namespace ID Slug. This will be possible once sharable color packs are added.
## Creating a Color
Once you've created your first namespace, click the "+" button inside the namespace section to create a color. To edit a color that you've previously created, either click on the color name or right click and select "Edit Color" from the context menu.
![Create Color (Primary Color)](../assets/custom_color_primary_only.png)
### Name
The display name for the color, used for presentation. You may occasionally see the color name followed by the [namespace name](#name) in parentheses to disambiguate it from other colors with the same name.
### ID Slug
Similar to [Namespace ID Slugs](#id-slug), the ID Slug is used as an internal ID and is automatically derived from the tag color name.
<!-- prettier-ignore -->
!!! note
It's currently not possible to manually edit the Color ID Slug. This will be possible once sharable color packs are added.
### Primary Color
The primary color is used as the main tag color and by default is used as the background color with the text and border colors being derived from this color.
### Secondary Color
By default, the secondary color is only used as an optional override for the tag text color. This color can be cleared by clicking the adjacent "Reset" button.
![Create Color (Secondary Color)](../assets/custom_color_no_border.png)
The secondary color can also be used as the tag border color by checking the "Use Secondary Color for Border" box.
![Create Color (Use Secondary for Border)](../assets/custom_color_border.png)
## Using Colors
When editing a tag, click the tag color button to bring up the tag color selection panel. From here you can choose any built-in TagStudio color as well as any of your custom colors.
![Tag Color Selection](../assets/tag_color_selection.png)

View File

@@ -0,0 +1,20 @@
---
tags:
- Upcoming Feature
---
# Tag Overrides
Tag overrides are the ability to add or remove [parent tags](tag.md#parent-tags) from a [tag](tag.md) on a per- [entry](entry.md) basis.
## Examples
<figure markdown="span">
![Example 1](../assets/tag_override_ex-1.png){ height="300" }
<figcaption>Ex. 1 - Comparing standard tag composition vs additive and subtractive inheritance overrides.</figcaption>
</figure>
<figure markdown="span">
![Example 2](../assets/tag_override_ex-2.png){ height="300" }
<figcaption>Ex. 2 - Parent tag swap using tag overrides.</figcaption>
</figure>

View File

@@ -0,0 +1,4 @@
---
title: Changelog
---
--8<-- "CHANGELOG.md"

217
docs/updates/roadmap.md Normal file
View File

@@ -0,0 +1,217 @@
# Feature Roadmap
This checklist details the current and remaining features required at a minimum for TagStudio to be considered “Feature Complete”. This list is _not_ a definitive list for additional feature requests and PRs as they come in, but rather an outline of my personal core feature set intended for TagStudio.
## Priorities
Features are broken up into the following priority levels, with nested priorities referencing their relative priority for the overall feature (i.e. A [LOW] priority feature can have a [HIGH] priority element but it otherwise still a [LOW] priority item overall):
- [HIGH] - Core feature
- [MEDIUM] - Important but not necessary
- [LOW] - Just nice to have
## Version Milestones
These version milestones are rough estimations for when the previous core features will be added. For a more definitive idea for when features are coming, please reference the current GitHub [milestones](https://github.com/TagStudioDev/TagStudio/milestones).
<!-- prettier-ignore -->
!!! note
This list was created after the release of version 9.4
### v9.5
#### Core
- [x] SQL backend [HIGH]
#### Tags
- [x] Deleting Tags [HIGH]
- [ ] User-defined tag colors [HIGH]
- [x] ID based, not string or hex [HIGH]
- [x] Color name [HIGH]
- [x] Color value (hex) [HIGH]
- [x] Existing colors are now a set of base colors [HIGH]
- [x] [Tag Categories](../library/tag_categories.md) [HIGH]
- [x] Property available for tags that allow the tag and any inheriting from it to be displayed separately in the preview panel under a title [HIGH]
#### Search
- [x] Boolean operators [HIGH]
- [x] Filename search [HIGH]
- [x] Filetype search [HIGH]
- [x] Search by extension (e.g. ".jpg", ".png") [HIGH]
- [x] Optional consolidation of extension synonyms (i.e. ".jpg" can equal ".jpeg") [LOW]
- [x] Search by media type (e.g. "image", "video", "document") [MEDIUM]
- [x] Sort by date added [HIGH]
#### UI
- [ ] Translations _(Any applicable)_ [MEDIUM]
#### Performance
- [x] Thumbnail caching [HIGH]
### v9.6
#### Core
- [ ] Cached file property table (media duration, word count, dimensions, etc.) [MEDIUM]
#### Library
- [ ] Multiple Root Directories per Library [HIGH]
- [ ] `.ts_ignore` (`.gitignore`-style glob ignoring) [HIGH]
- [ ] Sharable Color Packs [MEDIUM]
- [ ] Human-readable (TOML) files containing tag data [HIGH]
- [ ] Importable [HIGH]
- [ ] Exportable [HIGH]
#### Tags
- [ ] Merging Tags [HIGH]
- [ ] [Component/HAS](../library/tag.md#component-tags) subtags [HIGH]
- [ ] Tag Icons [HIGH]
- [ ] Small Icons [HIGH]
- [ ] Large Icons for Profiles [MEDIUM]
- [ ] Built-in Icon Packs (i.e. Boxicons) [HIGH]
- [ ] User Defined Icons [HIGH]
- [ ] Multiple Languages for Tag Strings [MEDIUM]
- [ ] Title is tag name [HIGH]
- [ ] Title has tag color [MEDIUM]
- [ ] Tag marked as category does not display as a tag itself [HIGH]
- [ ] [Tag Overrides](../library/tag_overrides.md) [MEDIUM]
- [ ] Per-file overrides of subtags [HIGH]
#### Fields
- [ ] Datetime fields [HIGH]
- [ ] Custom field names [HIGH]
#### Search
- [ ] Field content search [HIGH]
- [ ] Sort by date created [HIGH]
- [ ] Sort by date modified [HIGH]
- [ ] Sort by filename [HIGH]
- [ ] HAS operator for composition tags [HIGH]
- [ ] Search bar rework
- [ ] Improved tag autocomplete [HIGH]
- [ ] Tags appear as widgets in search bar [HIGH]
#### UI
- [ ] File duration on video thumbnails [HIGH]
- [ ] 3D Model Previews [MEDIUM]
- [ ] STL Previews [HIGH]
- [ ] Word count/line count on text thumbnails [LOW]
- [ ] Settings Menu [HIGH]
- [ ] Application Settings [HIGH]
- [ ] Stored in system user folder/designated folder [HIGH]
- [ ] Library Settings [HIGH]
- [ ] Stored in `.TagStudio` folder [HIGH]
- [ ] Tagging Panel [HIGH]
Togglebale persistent main window panel or popout. Replaces the current tag manager.
- [ ] Top Tags [HIGH]
- [ ] Recent Tags [HIGH]
- [ ] Tag Search [HIGH]
- [ ] Pinned Tags [HIGH]
- [ ] New tabbed tag building UI to support the new tag features [HIGH]
### v9.7
#### Library
- [ ] [Entry groups](../library/entry_groups.md) [HIGH]
- [ ] Groups for files/entries where the same entry can be in multiple groups [HIGH]
- [ ] Ability to number entries within group [HIGH]
- [ ] Ability to set sorting method for group [HIGH]
- [ ] Ability to set custom thumbnail for group [HIGH]
- [ ] Group is treated as entry with tags and metadata [HIGH]
- [ ] Nested groups [MEDIUM]
#### Search
- [ ] Sort by relevance [HIGH]
- [ ] Sort by date taken (photos) [MEDIUM]
- [ ] Sort by file size [HIGH]
- [ ] Sort by file dimension (images/video) [LOW]
#### [Macros](../utilities/macro.md)
- [ ] Sharable Macros [MEDIUM]
- [ ] Standard notation format (TOML) contacting macro instructions [HIGH]
- [ ] Exportable [HIGH]
- [ ] Importable [HIGH]
- [ ] Triggers [HIGH]
- [ ] On new file [HIGH]
- [ ] On library refresh [HIGH]
- [ ] [...]
- [ ] Actions [HIGH]
- [ ] Add tag(s) [HIGH]
- [ ] Add field(s) [HIGH]
- [ ] Set field content [HIGH]
- [ ] [...]
#### UI
- [ ] Custom thumbnail overrides [MEDIUM]
- [ ] Toggle File Extension Label [MEDIUM]
- [ ] Toggle Duration Label [MEDIUM]
- [ ] Custom Tag Badges [LOW]
- [ ] Unified Media Player [HIGH]
- [ ] Auto-hiding player controls
- [x] Play/Pause [HIGH]
- [x] Loop [HIGH]
- [x] Toggle Autoplay [MEDIUM]
- [ ] Volume Control [HIGH]
- [x] Toggle Mute [HIGH]
- [ ] Timeline scrubber [HIGH]
- [ ] Fullscreen [MEDIUM]
- [ ] Library list view [HIGH]
- [ ] Configurable page size [HIGH]
### v9.8
#### Library
- [ ] Automatic Entry Relinking [HIGH]
- [ ] Detect Renames [HIGH]
- [ ] Detect Moves [HIGH]
- [ ] Detect Deletions [HIGH]
#### Search
- [ ] OCR search [LOW]
- [ ] Fuzzy Search [LOW]
### v9.9
#### Library
- [ ] Exportable Library Data [HIGH]
- [ ] Standard notation format (i.e. JSON) contacting all library data [HIGH]
#### Tags
- [ ] Tag Packs [MEDIUM]
- [ ] Human-readable (TOML) files containing tag data [HIGH]
- [ ] Multiple Languages for Tag Strings [MEDIUM]
- [ ] Importable [HIGH]
- [ ] Exportable [HIGH]
- [ ] Conflict resolution [HIGH]
### v10.0
- [ ] All remaining [HIGH] and optional [MEDIUM] features
### Post v10.0
#### Core
- [ ] Core Library/API
- [ ] Plugin Support

View File

@@ -0,0 +1,46 @@
# Save Format Changes
This page outlines the various changes made the TagStudio save file format over time, sometimes referred to as the "database" or "database file".
## JSON
| First Used | Last Used | Format | Location |
| ---------- | ----------------------------------------------------------------------- | ------ | --------------------------------------------- |
| v1.0.0 | [v9.4.2](https://github.com/TagStudioDev/TagStudio/releases/tag/v9.4.2) | JSON | `<Library Folder>`/.TagStudio/ts_library.json |
The legacy database format for public TagStudio releases [v9.1](https://github.com/TagStudioDev/TagStudio/tree/Alpha-v9.1) through [v9.4.2](https://github.com/TagStudioDev/TagStudio/releases/tag/v9.4.2). Variations of this format had been used privately since v1.0.0.
Replaced by the new SQLite format introduced in TagStudio [v9.5.0 Pre-Release 1](https://github.com/TagStudioDev/TagStudio/releases/tag/v9.5.0-pr1).
## DB_VERSION 6
| First Used | Last Used | Format | Location |
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------ | ----------------------------------------------- |
| [v9.5.0-PR1](https://github.com/TagStudioDev/TagStudio/releases/tag/v9.5.0-pr1) | [v9.5.0-PR1](https://github.com/TagStudioDev/TagStudio/releases/tag/v9.5.0-pr1) | SQLite | `<Library Folder>`/.TagStudio/ts_library.sqlite |
The first public version of the SQLite save file format.
Migration from the legacy JSON format is provided via a walkthrough when opening a legacy library in TagStudio [v9.5.0 Pre-Release 1](https://github.com/TagStudioDev/TagStudio/releases/tag/v9.5.0-pr1) or later.
## DB_VERSION 7
| First Used | Last Used | Format | Location |
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------ | ----------------------------------------------- |
| [v9.5.0-PR2](https://github.com/TagStudioDev/TagStudio/releases/tag/v9.5.0-pr2) | [v9.5.0-PR3](https://github.com/TagStudioDev/TagStudio/releases/tag/v9.5.0-pr3) | SQLite | `<Library Folder>`/.TagStudio/ts_library.sqlite |
### Changes
- Repairs "Description" fields to use a TEXT_LINE key instead of a TEXT_BOX key.
- Repairs tags that may have a disambiguation_id pointing towards a deleted tag.
## DB_VERSION 8
| First Used | Last Used | Format | Location |
| ------------------------------------------------------------------------------- | --------- | ------ | ----------------------------------------------- |
| [v9.5.0-PR4](https://github.com/TagStudioDev/TagStudio/releases/tag/v9.5.0-pr4) | _Current_ | SQLite | `<Library Folder>`/.TagStudio/ts_library.sqlite |
### Changes
- Adds the `color_border` column to `tag_colors` table. Used for instructing the [secondary color](../library/tag_color.md#secondary-color) to apply to a tag's border as a new optional behavior.
- Adds three new default colors: "Burgundy (TagStudio Shades)", "Dark Teal (TagStudio Shades)", and "Dark Lavender (TagStudio Shades)".
- Updates Neon colors to use the the new `color_border` property.

64
docs/usage.md Normal file
View File

@@ -0,0 +1,64 @@
# Usage
## Creating/Opening a Library
With TagStudio opened, start by creating a new library or opening an existing one using File -> Open/Create Library from the menu bar. TagStudio will automatically create a new library from the chosen directory if one does not already exist. Upon creating a new library, TagStudio will automatically scan your folders for files and add those to your library (no files are moved during this process!).
## Refreshing the Library
Libraries under 10,000 files automatically scan for new or modified files when opened. In order to refresh the library manually, select "Refresh Directories" under the File menu.
## Adding Tags to File Entries
Access the "Add Tag" search box by either clicking on the "Add Tag" button at the bottom of the right sidebar, accessing the "Add Tags to Selected" option from the File menu, or by pressing <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>T</kbd>.
From here you can search for existing tags or create a new one if the one you're looking for doesn't exist. Click the “+” button next to any tags you want to to the currently selected file entries. To quickly add the top result, press the <kbd>Enter</kbd>/<kbd>Return</kbd> key to add the the topmost tag and reset the tag search. Press <kbd>Enter</kbd>/<kbd>Return</kbd> once more to close the dialog box. By using this method, you can quickly add various tags in quick succession just by using the keyboard!
To remove a tag from a file entry, hover over the tag in the preview panel and click on the "-" icon that appears.
## Adding Metadata to File Entries
To add a metadata field to a file entry, start by clicking the “Add Field” button at the bottom of the preview panel. From the dropdown menu, select the type of metadata field youd like to add to the entry
## Editing Metadata Fields
### Text Line / Text Box
Hover over the field and click the pencil icon. From there, add or edit text in the dialog box popup.
## Creating Tags
Create a new tag by accessing the "New Tag" option from the Edit menu or by pressing <kbd>Ctrl</kbd>+<kbd>T</kbd>. In the tag creation panel, enter a tag name, optional shorthand name, optional tag aliases, optional parent tags, and an optional color.
- The tag **name** is the base name of the tag. **_This does NOT have to be unique!_**
- The tag **shorthand** is a special type of alias that displays in situations where screen space is more valuable, notably with name disambiguation.
- **Aliases** are alternate names for a tag. These let you search for terms other than the exact tag name in order to find the tag again.
- **Parent Tags** are tags in which this this tag can substitute for in searches. In other words, tags under this section are parents of this tag.
- Parent tags with the disambiguation check next to them will be used to help disambiguate tag names that may not be unique.
- For example: If you had a tag for "Freddy Fazbear", you might add "Five Nights at Freddy's" as one of the parent tags. If the disambiguation box is checked next to "Five Nights at Freddy's" parent tag, then the tag "Freddy Fazbear" will display as "Freddy Fazbear (Five Nights at Freddy's)". Furthermore, if the "Five Nights at Freddy's" tag has a shorthand like "FNAF", then the "Freddy Fazbear" tag will display as "Freddy Fazbear (FNAF)".
- The **color** option lets you select an optional color palette to use for your tag.
- The **"Is Category"** property lets you treat this tag as a category under which itself and any child tags inheriting from it will be sorted by inside the preview panel.
### Tag Manager
You can manage your library of tags from opening the "Tag Manager" panel from Edit -> "Manage Tags". From here you can create, search for, edit, and permanently delete any tags you've created in your library.
## Editing Tags
To edit a tag, click on it inside the preview panel or right-click the tag and select “Edit Tag” from the context menu.
## Relinking Moved Files
Inevitably some of the files inside your library will be renamed, moved, or deleted. If a file has been renamed or moved, TagStudio will display the thumbnail as a red broken chain link. To relink moved files or delete these entries, select the "Manage Unlinked Entries" option under the Tools menu. Click the "Refresh" button to scan your library for unlinked entries. Once complete, you can attempt to “Search & Relink” any unlinked file entries to their respective files, or “Delete Unlinked Entries” in the event the original files have been deleted and you no longer wish to keep their entries inside your library.
<!-- prettier-ignore -->
!!! warning
There is currently no method to relink entries to files that have been renamed - only moved or deleted. This is a high priority for future releases.
<!-- prettier-ignore -->
!!! warning
If multiple matches for a moved file are found (matches are currently defined as files with a matching filename as the original), TagStudio will currently ignore the match groups. Adding a GUI for manual selection, as well as smarter automated relinking, are high priorities for future versions.
### Saving the Library
As of version 9.5, libraries are saved automatically as you go. To save a backup of your library, select File -> Save Library Backup from the menu bar.

46
docs/utilities/macro.md Normal file
View File

@@ -0,0 +1,46 @@
# Tools & Macros
Tools and macros are features that serve to create a more fluid [library](../library/index.md)-managing process, or provide some extra functionality. Please note that some are still in active development and will be fleshed out in future updates.
## Tools
### Fix Unlinked Entries
This tool displays the number of unlinked [entries](../library/entry.md), and some options for their resolution.
Refresh
: Scans through the library and updates the unlinked entry count.
Search & Relink
: Attempts to automatically find and reassign missing files.
Delete Unlinked Entries
: Displays a confirmation prompt containing the list of all missing files to be deleted before committing to or cancelling the operation.
### Fix Duplicate Files
This tool allows for management of duplicate files in the library using a [DupeGuru](https://dupeguru.voltaicideas.net/) file.
Load DupeGuru File
: load the "results" file created from a DupeGuru scan
Mirror Entries
: Duplicate entries will have their contents mirrored across all instances. This allows for duplicate files to then be deleted with DupeGuru as desired, without losing the [field](../library/field.md) data that has been assigned to either. (Once deleted, the "Fix Unlinked Entries" tool can be used to clean up the duplicates)
### Create Collage
This tool is a preview of an upcoming feature. When selected, TagStudio will generate a collage of all the contents in a Library, which can be found in the Library folder ("/your-folder/.TagStudio/collages/"). Note that this feature is still in early development, and doesn't yet offer any customization options.
## Macros
### Auto-fill [WIP]
Tool is in development and will be documented in future update.
### Sort fields
Tool is in development, will allow for user-defined sorting of [fields](../library/field.md).
### Folders to Tags
Creates tags from the existing folder structure in the library, which are previewed in a hierarchy view for the user to confirm. A tag will be created for each folder and applied to all entries, with each subfolder being linked to the parent folder as a [parent tag](../library/tag.md#parent-tags). Tags will initially be named after the folders, but can be fully edited and customized afterwards.

544
flake.lock generated
View File

@@ -1,12 +1,429 @@
{
"nodes": {
"cachix": {
"inputs": {
"devenv": "devenv_2",
"flake-compat": [
"devenv",
"flake-compat"
],
"nixpkgs": [
"devenv",
"nixpkgs"
],
"pre-commit-hooks": [
"devenv",
"pre-commit-hooks"
]
},
"locked": {
"lastModified": 1712055811,
"narHash": "sha256-7FcfMm5A/f02yyzuavJe06zLa9hcMHsagE28ADcmQvk=",
"owner": "cachix",
"repo": "cachix",
"rev": "02e38da89851ec7fec3356a5c04bc8349cae0e30",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "cachix",
"type": "github"
}
},
"devenv": {
"inputs": {
"cachix": "cachix",
"flake-compat": "flake-compat_2",
"nix": "nix_2",
"nixpkgs": "nixpkgs_2",
"pre-commit-hooks": "pre-commit-hooks"
},
"locked": {
"lastModified": 1724763216,
"narHash": "sha256-oW2bwCrJpIzibCNK6zfIDaIQw765yMAuMSG2gyZfGv0=",
"owner": "cachix",
"repo": "devenv",
"rev": "1e4ef61205b9aa20fe04bf1c468b6a316281c4f1",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "devenv",
"type": "github"
}
},
"devenv-root": {
"flake": false,
"locked": {
"narHash": "sha256-d6xi4mKdjkX2JFicDIv5niSzpyI0m/Hnm8GGAIU04kY=",
"type": "file",
"url": "file:///dev/null"
},
"original": {
"type": "file",
"url": "file:///dev/null"
}
},
"devenv_2": {
"inputs": {
"flake-compat": [
"devenv",
"cachix",
"flake-compat"
],
"nix": "nix",
"nixpkgs": "nixpkgs",
"poetry2nix": "poetry2nix",
"pre-commit-hooks": [
"devenv",
"cachix",
"pre-commit-hooks"
]
},
"locked": {
"lastModified": 1708704632,
"narHash": "sha256-w+dOIW60FKMaHI1q5714CSibk99JfYxm0CzTinYWr+Q=",
"owner": "cachix",
"repo": "devenv",
"rev": "2ee4450b0f4b95a1b90f2eb5ffea98b90e48c196",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "python-rewrite",
"repo": "devenv",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1725024810,
"narHash": "sha256-ODYRm8zHfLTH3soTFWE452ydPYz2iTvr9T8ftDMUQ3E=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "af510d4a62d071ea13925ce41c95e3dec816c01d",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1689068808,
"narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_3": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"devenv",
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"nix": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": [
"devenv",
"cachix",
"devenv",
"nixpkgs"
],
"nixpkgs-regression": "nixpkgs-regression"
},
"locked": {
"lastModified": 1712911606,
"narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=",
"owner": "domenkozar",
"repo": "nix",
"rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12",
"type": "github"
},
"original": {
"owner": "domenkozar",
"ref": "devenv-2.21",
"repo": "nix",
"type": "github"
}
},
"nix-github-actions": {
"inputs": {
"nixpkgs": [
"devenv",
"cachix",
"devenv",
"poetry2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1688870561,
"narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=",
"owner": "nix-community",
"repo": "nix-github-actions",
"rev": "165b1650b753316aa7f1787f3005a8d2da0f5301",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-github-actions",
"type": "github"
}
},
"nix2container": {
"inputs": {
"flake-utils": "flake-utils_3",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1724996935,
"narHash": "sha256-njRK9vvZ1JJsP8oV2OgkBrpJhgQezI03S7gzskCcHos=",
"owner": "nlewo",
"repo": "nix2container",
"rev": "fa6bb0a1159f55d071ba99331355955ae30b3401",
"type": "github"
},
"original": {
"owner": "nlewo",
"repo": "nix2container",
"type": "github"
}
},
"nix_2": {
"inputs": {
"flake-compat": [
"devenv",
"flake-compat"
],
"nixpkgs": [
"devenv",
"nixpkgs"
],
"nixpkgs-regression": "nixpkgs-regression_2"
},
"locked": {
"lastModified": 1712911606,
"narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=",
"owner": "domenkozar",
"repo": "nix",
"rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12",
"type": "github"
},
"original": {
"owner": "domenkozar",
"ref": "devenv-2.21",
"repo": "nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1712473363,
"narHash": "sha256-TIScFAVdI2yuybMxxNjC4YZ/j++c64wwuKbpnZnGiyU=",
"lastModified": 1692808169,
"narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9201b5ff357e781bf014d0330d18555695df7ba8",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-qt6": {
"locked": {
"lastModified": 1718428119,
"narHash": "sha256-WdWDpNaq6u1IPtxtYHHWpl5BmabtpmLnMAx0RdJ/vo8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e6cea36f83499eb4e9cd184c8a8e823296b50ad5",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e6cea36f83499eb4e9cd184c8a8e823296b50ad5",
"type": "github"
}
},
"nixpkgs-regression": {
"locked": {
"lastModified": 1643052045,
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github"
}
},
"nixpkgs-regression_2": {
"locked": {
"lastModified": 1643052045,
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1710695816,
"narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "614b4613980a522ba49f0d194531beddbb7220d3",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1713361204,
"narHash": "sha256-TA6EDunWTkc5FvDCqU3W2T3SFn0gRZqh6D/hJnM02MM=",
"owner": "cachix",
"repo": "devenv-nixpkgs",
"rev": "285676e87ad9f0ca23d8714a6ab61e7e027020c6",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "rolling",
"repo": "devenv-nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1724819573,
"narHash": "sha256-GnR7/ibgIH1vhoy8cYdmXE6iyZqKqFxQSVkFgosBh6w=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "e89cf1c932006531f454de7d652163a9a5c86668",
"rev": "71e91c409d1e654808b2621f28a327acfdad8dc2",
"type": "github"
},
"original": {
@@ -16,9 +433,128 @@
"type": "github"
}
},
"poetry2nix": {
"inputs": {
"flake-utils": "flake-utils",
"nix-github-actions": "nix-github-actions",
"nixpkgs": [
"devenv",
"cachix",
"devenv",
"nixpkgs"
]
},
"locked": {
"lastModified": 1692876271,
"narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=",
"owner": "nix-community",
"repo": "poetry2nix",
"rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "poetry2nix",
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": [
"devenv",
"flake-compat"
],
"flake-utils": "flake-utils_2",
"gitignore": "gitignore",
"nixpkgs": [
"devenv",
"nixpkgs"
],
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1713775815,
"narHash": "sha256-Wu9cdYTnGQQwtT20QQMg7jzkANKQjwBD9iccfGKkfls=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "2ac4dcbf55ed43f3be0bae15e181f08a57af24a4",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
"devenv": "devenv",
"devenv-root": "devenv-root",
"flake-parts": "flake-parts",
"nix2container": "nix2container",
"nixpkgs": "nixpkgs_3",
"nixpkgs-qt6": "nixpkgs-qt6",
"systems": "systems_4"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_4": {
"locked": {
"lastModified": 1689347949,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
"owner": "nix-systems",
"repo": "default-linux",
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default-linux",
"type": "github"
}
}
},

268
flake.nix
View File

@@ -1,70 +1,210 @@
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
description = "TagStudio";
outputs = { self, nixpkgs, }:
let
pkgs = nixpkgs.legacyPackages.x86_64-linux;
in {
devShells.x86_64-linux.default = pkgs.mkShell {
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [
pkgs.gcc-unwrapped
pkgs.zlib
pkgs.libglvnd
pkgs.glib
pkgs.stdenv.cc.cc
pkgs.fontconfig
pkgs.libxkbcommon
pkgs.xorg.libxcb
pkgs.freetype
pkgs.dbus
pkgs.qt6.qtwayland
pkgs.qt6.full
pkgs.qt6.qtbase
pkgs.zstd
];
buildInputs = with pkgs; [
cmake
gdb
zstd
qt6.qtbase
qt6.full
qt6.qtwayland
qtcreator
python312Packages.pip
python312Full
python312Packages.virtualenv # run virtualenv .
python312Packages.pyusb # fixes the pyusb 'No backend available' when installed directly via pip
inputs = {
devenv.url = "github:cachix/devenv";
libgcc
makeWrapper
bashInteractive
glib
libxkbcommon
freetype
binutils
dbus
coreutils
libGL
libGLU
fontconfig
xorg.libxcb
# this is for the shellhook portion
qt6.wrapQtAppsHook
makeWrapper
bashInteractive
];
# set the environment variables that Qt apps expect
shellHook = ''
export QT_QPA_PLATFORM=wayland
export LIBRARY_PATH=/usr/lib:/usr/lib64:$LIBRARY_PATH
# export LD_LIBRARY_PATH=${pkgs.stdenv.cc.cc.lib}/lib/:/run/opengl-driver/lib/
export QT_PLUGIN_PATH=${pkgs.qt6.qtbase}/${pkgs.qt6.qtbase.qtPluginPrefix}
bashdir=$(mktemp -d)
makeWrapper "$(type -p bash)" "$bashdir/bash" "''${qtWrapperArgs[@]}"
exec "$bashdir/bash"
'';
devenv-root = {
url = "file+file:///dev/null";
flake = false;
};
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
nix2container = {
url = "github:nlewo/nix2container";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
# Pinned to Qt version 6.7.1
nixpkgs-qt6.url = "github:NixOS/nixpkgs/e6cea36f83499eb4e9cd184c8a8e823296b50ad5";
systems.url = "github:nix-systems/default-linux";
};
outputs =
{
flake-parts,
nixpkgs,
nixpkgs-qt6,
self,
systems,
...
}@inputs:
flake-parts.lib.mkFlake { inherit inputs; } {
imports = [ inputs.devenv.flakeModule ];
systems = import systems;
perSystem =
{
config,
pkgs,
system,
...
}:
let
inherit (nixpkgs) lib;
qt6Pkgs = import nixpkgs-qt6 { inherit system; };
in
{
formatter = pkgs.nixfmt-rfc-style;
devenv.shells = rec {
default = tagstudio;
tagstudio =
let
cfg = config.devenv.shells.tagstudio;
in
{
# NOTE: many things were simply transferred over from previous,
# there must be additional work in ensuring all relevant dependencies
# are in place (and no extraneous). I have already spent much
# work making this in the first place and just need to get it out
# there, especially after my promises. Would appreciate any help
# (possibly PRs!) on taking care of this. Otherwise, just expect
# this to get ironed out over time.
#
# Thank you! -Xarvex
devenv.root =
let
devenvRoot = builtins.readFile inputs.devenv-root.outPath;
in
# If not overriden (/dev/null), --impure is necessary.
pkgs.lib.mkIf (devenvRoot != "") devenvRoot;
name = "TagStudio";
# Derived from previous flake iteration.
packages =
(with pkgs; [
cmake
binutils
coreutils
dbus
fontconfig
freetype
gdb
glib
libGL
libGLU
libgcc
libxkbcommon
mypy
ruff
xorg.libxcb
xorg.libX11
zstd
])
++ (with qt6Pkgs; [
qt6.full
qt6.qtbase
qt6.qtwayland
qtcreator
]);
enterShell =
let
setQtEnv =
pkgs.runCommand "set-qt-env"
{
buildInputs = with qt6Pkgs.qt6; [
qtbase
];
nativeBuildInputs =
(with pkgs; [
makeShellWrapper
])
++ (with qt6Pkgs.qt6; [
wrapQtAppsHook
]);
}
''
makeShellWrapper "$(type -p sh)" "$out" "''${qtWrapperArgs[@]}"
sed "/^exec/d" -i "$out"
'';
in
''
source ${setQtEnv}
'';
scripts.tagstudio.exec = ''
python ${cfg.devenv.root}/tagstudio/tag_studio.py
'';
env = {
QT_QPA_PLATFORM = "wayland;xcb";
# Derived from previous flake iteration.
# Not desired given LD_LIBRARY_PATH pollution.
# See supposed alternative below, further research required.
LD_LIBRARY_PATH = lib.makeLibraryPath (
(with pkgs; [
dbus
fontconfig
freetype
gcc-unwrapped
glib
libglvnd
libkrb5
libpulseaudio
libva
libxkbcommon
openssl
stdenv.cc.cc.lib
wayland
xorg.libxcb
xorg.libX11
xorg.libXrandr
zlib
zstd
])
++ (with qt6Pkgs.qt6; [
qtbase
qtwayland
full
])
);
};
languages.python = {
enable = true;
venv = {
enable = true;
quiet = true;
requirements =
let
excludeDeps =
req: deps:
builtins.concatStringsSep "\n" (
builtins.filter (line: !(lib.any (elem: lib.hasPrefix elem line) deps)) (lib.splitString "\n" req)
);
in
''
${builtins.readFile ./requirements.txt}
${excludeDeps (builtins.readFile ./requirements-dev.txt) [
"mypy"
"ruff"
]}
'';
};
# Should be able to replace LD_LIBRARY_PATH?
# Was not quite able to get working,
# will be consulting cachix community. -Xarvex
# libraries = with pkgs; [ ];
};
};
};
};
};
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 859 KiB

138
mkdocs.yml Normal file
View File

@@ -0,0 +1,138 @@
# yaml-language-server: $schema=https://squidfunk.github.io/mkdocs-material/schema.json
# MkDocs: https://www.mkdocs.org/
# Material for MkDocs: https://squidfunk.github.io/mkdocs-material/
# To install:
# pip install mkdocs-material
# To run the preview server:
# mkdocs serve
site_name: TagStudio
site_description: "A User-Focused Photo & File Management System"
site_url: https://docs.tagstud.io/
repo_url: https://github.com/TagStudioDev/TagStudio
edit_uri: blob/main/docs/
repo_name: TagStudioDev/TagStudio
extra:
social:
- icon: fontawesome/brands/github
link: https://github.com/TagStudioDev
- icon: fontawesome/brands/discord
link: https://discord.gg/hRNnVKhF2G
tags:
Upcoming Feature: upcoming
# by default the navigation is an alphanumerically sorted,
# nested list of all the Markdown files found within the /docs directory
# where index files are always first
# uncomment the following to configure the navigation manually:
# nav:
# - Home:
# - index.md
# - install.md
# - usage.md
# - Library:
# - library/index.md
# - library/entry.md
# - library/entry_groups.md
# - library/field.md
# - library/tag.md
# - library/tag_categories.md
# - library/tag_overrides.md
# - Utilities:
# - utilities/macro.md
# - Updates:
# - updates/changelog.md
# - updates/roadmap.md
# - updates/db_migration.md
theme:
name: material
palette:
# Palette toggle for automatic mode
- media: "(prefers-color-scheme)"
toggle:
icon: material/brightness-auto
name: Switch to light mode
# Palette toggle for light mode
- media: "(prefers-color-scheme: light)"
scheme: default
primary: deep purple
accent: deep purple
toggle:
icon: material/brightness-7
name: Switch to dark mode
# Palette toggle for dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: deep purple
accent: deep purple
toggle:
icon: material/brightness-4
name: SSwitch to system preference
logo: assets/icon.png
favicon: assets/icon.ico
font: false # use system fonts
language: en
features:
- navigation.instant
- navigation.indexes
- navigation.tracking
- navigation.expand
- navigation.sections
#- navigation.tabs
#- content.tabs.link
#- navigation.top
- search.suggest
- content.code.annotate
- content.action.edit
icon:
repo: fontawesome/brands/github
tag:
upcoming: material/flask-outline
markdown_extensions:
# Python Markdown
- abbr
- admonition
- attr_list
- def_list
- footnotes
- md_in_html
- toc:
permalink: true
# Python Markdown Extensions
- pymdownx.arithmatex:
generic: true
- pymdownx.betterem:
smart_enable: all
- pymdownx.caret
- pymdownx.details
- pymdownx.highlight
- pymdownx.inlinehilite
- pymdownx.keys
- pymdownx.mark
- pymdownx.smartsymbols
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.tabbed:
alternate_style: true
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tilde
- pymdownx.snippets
plugins:
- search
- tags
- social: # social embed cards
enabled: !ENV [CI, false] # enabled only when running in CI (eg GitHub Actions)

View File

@@ -1,8 +1,60 @@
[project]
name = "TagStudio"
description = "A User-Focused Photo & File Management System."
version = "9.5.1"
license = "GPL-3.0-only"
readme = "README.md"
[tool.ruff]
exclude = ["main_window.py", "home_ui.py", "resources.py", "resources_rc.py"]
line-length = 100
[tool.ruff.lint.per-file-ignores]
"tagstudio/tests/**" = ["D", "E402"]
"tagstudio/src/qt/helpers/vendored/**" = ["B", "E", "N", "UP", "SIM115"]
[tool.ruff.lint.pydocstyle]
convention = "google"
[tool.ruff.lint]
select = ["B", "D", "E", "F", "FBT003", "I", "N", "SIM", "T20", "UP"]
ignore = ["D100", "D101", "D102", "D103", "D104", "D105", "D106", "D107"]
[tool.pyright]
ignore = [".venv/**"]
include = ["tagstudio/**"]
reportAny = false
reportImplicitStringConcatenation = false
# reportOptionalMemberAccess = false
reportUnannotatedClassAttribute = false
reportUnknownArgumentType = false
reportUnknownMemberType = false
reportUnusedCallResult = false
[tool.mypy]
strict_optional = false
disable_error_code = ["union-attr", "annotation-unchecked", "import-untyped"]
disable_error_code = ["func-returns-value", "import-untyped"]
explicit_package_bases = true
warn_unused_ignores = true
check_untyped_defs = true
mypy_path = ["tagstudio"]
[[tool.mypy.overrides]]
module = "tests.*"
ignore_errors = true
[[tool.mypy.overrides]]
module = "src.qt.main_window"
ignore_errors = true
[[tool.mypy.overrides]]
module = "src.qt.ui.home_ui"
ignore_errors = true
[[tool.mypy.overrides]]
module = "src.core.ts_core"
ignore_errors = true
[tool.pytest.ini_options]
#addopts = "-m 'not qt'"
qt_api = "pyside6"

View File

@@ -1,5 +1,8 @@
ruff==0.4.2
ruff==0.8.1
pre-commit==3.7.0
pytest==8.2.0
Pyinstaller==6.6.0
mypy==1.10.0
mypy==1.11.2
syrupy==4.7.1
pytest-qt==4.4.0
pytest-cov==5.0.0

View File

@@ -1,11 +1,20 @@
chardet==5.2.0
ffmpeg-python==0.2.0
humanfriendly==10.0
opencv_python>=4.8.0.74,<=4.9.0.80
mutagen==1.47.0
numpy==2.1.0
opencv_python==4.10.0.84
pillow-heif==0.16.0
pillow-jxl-plugin==1.3.0
Pillow==10.3.0
PySide6>=6.5.1.1,<=6.6.3.1
PySide6_Addons>=6.5.1.1,<=6.6.3.1
PySide6_Essentials>=6.5.1.1,<=6.6.3.1
pydub==0.25.1
PySide6_Addons==6.8.0.1
PySide6_Essentials==6.8.0.1
PySide6==6.8.0.1
rawpy==0.22.0
Send2Trash==1.8.3
SQLAlchemy==2.0.34
structlog==24.4.0
typing_extensions>=3.10.0.0,<=4.11.0
ujson>=5.8.0,<=5.9.0
rawpy==0.21.0
pillow-heif==0.16.0
chardet==5.2.0
vtf2img==0.1.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 531 KiB

View File

@@ -26,7 +26,7 @@ a = Analysis(
['tagstudio/tag_studio.py'],
pathex=[],
binaries=[],
datas=[('tagstudio/resources', 'resources')],
datas=[('tagstudio/resources', 'resources'), ('tagstudio/src', 'src')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
@@ -77,8 +77,8 @@ app = BUNDLE(
exe if coll is None else coll,
name='TagStudio.app',
icon=icon,
bundle_identifier='com.github.tagstudiodev',
version='0.0.0',
bundle_identifier='com.cyanvoxel.tagstudio',
version='9.5.1',
info_plist={
'NSAppleScriptEnabled': False,
'NSPrincipalClass': 'NSApplication',

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 172 B

View File

Before

Width:  |  Height:  |  Size: 151 B

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Some files were not shown because too many files have changed in this diff Show More