Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: (c) TagStudio Contributors
# SPDX-License-Identifier: GPL-3.0-only


---
patreon: cyanvoxel
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
---
name: Bug Report
description: File a bug or issue report.
title: '[Bug]: '
labels: ['Type: Bug']
title: "[Bug]: "
labels: ["Type: Bug"]
body:
- type: markdown
attributes:
Expand Down
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
---
name: Feature Request
description: Suggest a new feature.
title: '[Feature Request]: '
labels: ['Type: Enhancement']
title: "[Feature Request]: "
labels: ["Type: Enhancement"]
body:
- type: markdown
attributes:
Expand Down
25 changes: 13 additions & 12 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<!-- SPDX-FileCopyrightText: (c) TagStudio Contributors -->
<!-- SPDX-License-Identifier: GPL-3.0-only -->

### Summary

<!--
Expand All @@ -19,15 +20,15 @@ Thank you for your eagerness to contribute!

<!-- 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 -->
- 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 -->
2 changes: 1 addition & 1 deletion .github/workflows/mypy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
python-version: "3.12"
cache: pip

- name: Install Python dependencies
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish_docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
python-version: "3.12"
cache: pip

- name: Install Python dependencies
Expand All @@ -45,7 +45,7 @@ jobs:
key: mkdocs-material-${{ env.cache_id }}
path: .cache
restore-keys: |
mkdocs-material-
mkdocs-material-

- name: Execute mkdocs
run: mkdocs gh-deploy --force
2 changes: 1 addition & 1 deletion .github/workflows/pytest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
python-version: "3.12"
cache: pip

- &install-dependencies
Expand Down
33 changes: 16 additions & 17 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ jobs:
linux:
strategy:
matrix:
build-type: ['', portable]
build-type: ["", portable]
include:
- build-type: ''
build-flag: ''
suffix: ''
- build-type: ""
build-flag: ""
suffix: ""
- build-type: portable
build-flag: --portable
suffix: _portable
Expand All @@ -28,7 +28,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
python-version: "3.12"
cache: pip

- name: Install Python dependencies
Expand All @@ -50,18 +50,18 @@ jobs:
macos:
strategy:
matrix:
os-version: ['14', '15']
os-version: ["14", "15"]
include:
- os-version: '14'
- os-version: "14"
arch: x86_64
- os-version: '15'
- os-version: "15"
arch: aarch64

runs-on: macos-${{ matrix.os-version }}

env:
# INFO: Even though we run on 14, target towards compatibility
MACOSX_DEPLOYMENT_TARGET: '11.0'
MACOSX_DEPLOYMENT_TARGET: "11.0"

steps:
- name: Checkout repo
Expand All @@ -70,15 +70,14 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
python-version: "3.12"
cache: pip

- name: Install Python dependencies
run: |
python -m pip install --upgrade uv
uv pip install --system .[pyinstaller]


- name: Execute PyInstaller
run: |
pyinstaller tagstudio.spec
Expand All @@ -92,12 +91,12 @@ jobs:
windows:
strategy:
matrix:
build-type: ['', portable]
build-type: ["", portable]
include:
- build-type: ''
build-flag: ''
suffix: ''
file-end: ''
- build-type: ""
build-flag: ""
suffix: ""
file-end: ""
- build-type: portable
build-flag: --portable
suffix: _portable
Expand All @@ -112,7 +111,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
python-version: "3.12"
cache: pip

- name: Install Python dependencies
Expand Down
5 changes: 5 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: (c) TagStudio Contributors
# SPDX-License-Identifier: MIT

overrides/partials/*.html
tests/fixtures/json_library/.TagStudio/*.json
109 changes: 55 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<!-- SPDX-FileCopyrightText: (c) TagStudio Contributors -->
<!-- SPDX-License-Identifier: GPL-3.0-only -->

# TagStudio: A User-Focused Photo & File Management System

[![Downloads](https://img.shields.io/github/downloads/TagStudioDev/TagStudio/total.svg?maxAge=2592001)](https://github.com/TagStudioDev/TagStudio/releases)
Expand All @@ -23,11 +24,11 @@ TagStudio is a photo & file organization application with an underlying tag-base

## Contents

- [Feature Highlights](#feature-highlights)
- [Basic Usage](#basic-usage)
- [Installation](#installation)
- [Goals & Priorities](#goals--priorities)
- [FAQ](#faq)
- [Feature Highlights](#feature-highlights)
- [Basic Usage](#basic-usage)
- [Installation](#installation)
- [Goals & Priorities](#goals--priorities)
- [FAQ](#faq)

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!

Expand All @@ -45,45 +46,45 @@ All file types are supported in TagStudio libraries, just not all have dedicated

For a generalized list of what's currently supported:

- **Images**
- Raster Images (JPEG, PNG, etc.)
- Vector (SVG)
- Animated (GIF, WEBP, APNG)
- RAW Formats
- **Videos**
- **Plaintext Files**
- **Documents** _(If supported)_
- **eBooks** _(If supported)_
- **Photoshop PSDs**, **Blender Projects**, **Krita Projects**, and more!
- **Images**
- Raster Images (JPEG, PNG, etc.)
- Vector (SVG)
- Animated (GIF, WEBP, APNG)
- RAW Formats
- **Videos**
- **Plaintext Files**
- **Documents** _(If supported)_
- **eBooks** _(If supported)_
- **Photoshop PSDs**, **Blender Projects**, **Krita Projects**, and more!

### [Tags](https://docs.tagstud.io/tags) and [Fields](https://docs.tagstud.io/fields)

Tags represent an object or 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.

Tags currently consist of the following attributes:

- **Name**: The full name for your tag. **_This does NOT have to be unique!_**
- **Shorthand Name**: The shortest alternate name for your tag, used for abbreviations.
- **Aliases**: Alternate names your tag goes by.
- **Color**: The display color of your tag.
- **Parent Tags**: Other tags in which this tag inherits from. In practice, this means that this tag can be substituted in searches for any listed parent tags.
- Parent tags checked with the "disambiguation" checkbox 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)".
- **Is Category**: A property that when checked, treats this tag as a category in the preview panel.
- **Name**: The full name for your tag. **_This does NOT have to be unique!_**
- **Shorthand Name**: The shortest alternate name for your tag, used for abbreviations.
- **Aliases**: Alternate names your tag goes by.
- **Color**: The display color of your tag.
- **Parent Tags**: Other tags in which this tag inherits from. In practice, this means that this tag can be substituted in searches for any listed parent tags.
- Parent tags checked with the "disambiguation" checkbox 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)".
- **Is Category**: A property that when checked, treats this tag as a category in the preview panel.

Fields, like tags, are additional pieces of custom metadata that you can add to your file entries. Fields currently have several hardcoded names (e.g. "Title", "Author", "Series") but custom field names are planned for an upcoming update.

Field types currently include:

- **Text Lines**: Single lines of text.
- **Text Boxes**: Multi-line pieces of text.
- **Datetimes**: Dates and times.
- **Text Lines**: Single lines of text.
- **Text Boxes**: Multi-line pieces of text.
- **Datetimes**: Dates and times.

### [Search](https://docs.tagstud.io/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
- 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

## Basic Usage

Expand Down Expand Up @@ -167,11 +168,11 @@ See the [**Roadmap**](docs/roadmap.md) on the documentation site for a complete

### Overall Goals

- 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 user’s 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. It’s 2025, not 1995.
- 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 user’s 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. It’s 2025, not 1995.

### Project Priorities

Expand Down Expand Up @@ -199,29 +200,29 @@ See the [roadmap](https://docs.tagstud.io/roadmap) page for the core features be

The most important remaining features before I consider the program to be "feature complete" are:

- Custom names for Fields
- List views for files
- Multiple root directory support for libraries
- Improved file entry relinking
- File entry groups
- Sorting by file date modified and created
- Macros
- Improved search bar with visualized tags and improved autocomplete
- Side panel for easier tagging (pinned tags, recent tags, tag search, tag palette)
- Improved tag management interface
- Improved and finalized Tag Categories
- Fixed and improved mixed entry data displays (see: [#337](https://github.com/TagStudioDev/TagStudio/issues/337))
- Sharable tag data
- Separate core library + API
- Custom names for Fields
- List views for files
- Multiple root directory support for libraries
- Improved file entry relinking
- File entry groups
- Sorting by file date modified and created
- Macros
- Improved search bar with visualized tags and improved autocomplete
- Side panel for easier tagging (pinned tags, recent tags, tag search, tag palette)
- Improved tag management interface
- Improved and finalized Tag Categories
- Fixed and improved mixed entry data displays (see: [#337](https://github.com/TagStudioDev/TagStudio/issues/337))
- Sharable tag data
- Separate core library + API

### What features will NOT be added?

- 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/Claude/Gemini/_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: [Overall Goals/Privacy](#overall-goals)).
- With that being said, the future TagStudio API should be well-suited to connect to any sort of service you'd like, including machine learning models if so you choose. I just won't _personally_ add any native integrations with online services.
- 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/Claude/Gemini/_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: [Overall Goals/Privacy](#overall-goals)).
- With that being said, the future TagStudio API should be well-suited to connect to any sort of service you'd like, including machine learning models if so you choose. I just won't _personally_ add any native integrations with online services.

### Is a Rust port coming?

Expand Down
5 changes: 4 additions & 1 deletion REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ SPDX-FileCopyrightText = "(c) 2026 Boxicons"
SPDX-License-Identifier = "MIT"

[[annotations]]
path = ["src/tagstudio/resources/qt/images/volume.svg", "src/tagstudio/resources/qt/images/volume_mute.svg"]
path = [
"src/tagstudio/resources/qt/images/volume.svg",
"src/tagstudio/resources/qt/images/volume_mute.svg",
]
SPDX-FileCopyrightText = "(c) github:google/material-design-icons Contributors"
SPDX-License-Identifier = "Apache-2.0"
5 changes: 1 addition & 4 deletions contrib/.vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@
"program": "${workspaceRoot}/src/tagstudio/main.py",
"console": "integratedTerminal",
"justMyCode": true,
"args": [
"-o",
"~/Documents/Example"
]
"args": ["-o", "~/Documents/Example"]
}
]
}
Loading
Loading