Skip to content

efirlus/stashsorter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Stash Sorter

Advanced scene group sorting and management tool for StashApp

πŸ“– Overview

While StashApp natively supports only single-field sorting, Stash Sorter provides advanced sorting capabilities including multi-field sorting, random sorting, interleaved sorting, and more.

Why Stash Sorter?

This project was developed with a focus on portability and independence:

  • Pure GraphQL API: Instead of relying on external libraries like stashapp-tools, this tool communicates directly with Stash via the GraphQL API. This ensures lightweight execution and avoids issues caused by library version mismatches or incomplete documentation.
  • AI-Optimized Architecture: The entire logic was orchestrated by Claude Code, utilizing raw API calls to ensure precise control over data manipulation without the overhead of third-party wrappers.

Key Features

  • 🎯 Multi-Field Sorting: Complex sorting with multiple fields (e.g., rating β†’ date β†’ studio)
  • 🎲 Random Sorting: Randomly shuffle scenes with the same field values
  • πŸ”€ Interleaved Sorting: Randomly interleave groups while maintaining order within each group
  • πŸ” Advanced Filters: Precise scene search with 8 filter types
  • πŸ“‹ Template System: Save and reuse custom sorting configurations
  • ♻️ Group Management: Auto-remove played scenes, re-sort existing groups
  • πŸ’» User-Friendly: Interactive menu-based interface
  • πŸ›‘οΈ DRY_RUN Mode: Safe testing before making actual changes

πŸš€ Quick Start

1. Requirements

  • Python 3.8 or higher
  • StashApp server (v0.20.0 or higher recommended)
  • StashApp API Key

2. Installation

# Clone the repository
git clone <repository-url>
cd stashsorter

# Install dependencies
pip install -r requirements.txt

3. Configuration

Create a .env file and configure the following:

STASH_URL=http://localhost:9999/graphql
STASH_API_KEY=your_api_key_here

# Optional settings
LOG_LEVEL=INFO
DRY_RUN=false
TIMEOUT=30
MAX_RETRIES=3

How to get your API Key:

  1. Open StashApp web interface
  2. Go to Settings β†’ Security β†’ Generate API Key

4. Run

python run.py

πŸ“š Usage

Main Menu

1. Create Sorted Group - Create new group with filters and sorting rules
2. Manage Group - Remove scenes and re-sort existing groups
3. Exit

Creating a Sorted Group

Phase 1: Filter Setup

Define criteria to search for scenes.

Available Filters:

  • Rating (rating100)
  • Path (path)
  • Tags (tags)
  • Play Count (play_count)
  • Performers (performers)
  • Studio (studio)
  • Date (date)
  • Organized (organized)

Example:

Rating >= 80 + Play Count = 0 + Path includes "/favorites/"

Phase 2: Sorting Method Selection

Option A: Use Template

  • Select from built-in templates:
    • Interleaved by Folder, Sorted by Filename
    • Interleaved by Folder, Sorted by Path
    • Random Folder + Rating Descending
    • Random Studio + Rating Descending
  • Or use your saved custom templates

Option B: Custom Sort

  • Manually configure sort keys
  • Optionally save as a template for future use

Sort Directions:

  • asc: Ascending order (smallest first)
  • desc: Descending order (largest first)
  • random: Random shuffle
  • interleaved: Randomly interleave groups, maintain order within groups

Example:

1. rating100 (desc) - Highest rated first
2. date (asc) - Oldest first
3. studio.parent_studio.name (random) - Random within each studio

Phase 3: Preview & Confirmation

  • Preview first 50 sorted scenes
  • View directory distribution analysis
  • View directory transition patterns
  • Options:
    • Confirm and proceed to group creation
    • Re-sort with different settings
    • Cancel

Phase 4: Group Creation

  • Enter group name
  • Review final summary
  • Create group and add scenes

Group Management

Remove Played Scenes

Automatically removes scenes with play_count > 0 from a group.

  1. Enter group ID
  2. Review list of scenes to be removed
  3. Confirm and bulk remove

Re-sort Group

Re-sorts scenes in a group using sorting rules stored in the group description.

  1. Enter group ID
  2. Auto-parse sorting rules (or manually input)
  3. Re-sort scenes and update group

🎯 Use Cases

Example 1: High-Rated Unwatched Scenes

Filters:
- rating100 >= 80
- play_count = 0

Sort:
1. rating100 (desc)
2. date (asc)

Result: Unwatched scenes rated 80+ sorted by rating, then by date

Example 2: Interleaved Folder Playlist

Filters:
- path INCLUDES "/favorites/"
- organized = true

Sort:
1. files.0.parent_folder.path (interleaved)
2. files.0.basename (asc)

Result: Folders randomly interleaved, files within each folder sorted alphabetically

Example 3: Random Studio Rotation

Filters:
- date >= 2024-01-01

Sort:
1. studio.name (random)
2. rating100 (desc)

Result: Studios in random order, scenes within each studio sorted by rating

Example 4: Date + Performer Sorting

Filters:
- date >= 2024-01-01
- performers INCLUDES_ALL [1, 5, 10]

Sort:
1. date (desc)
2. performers.0.name (asc)
3. rating100 (desc)

Result: Latest first, then by performer name, then by rating

πŸ“‚ Project Structure

stashsorter/
β”œβ”€β”€ run.py                              # Main launcher
β”œβ”€β”€ lib/                                # Core library modules
β”‚   β”œβ”€β”€ config.py                       # Configuration
β”‚   β”œβ”€β”€ logger.py                       # Logging
β”‚   β”œβ”€β”€ stash_client.py                 # GraphQL client
β”‚   β”œβ”€β”€ validators.py                   # Validation functions
β”‚   β”œβ”€β”€ ui_helpers.py                   # UI helper functions
β”‚   β”œβ”€β”€ sorters.py                      # Sorting logic
β”‚   β”œβ”€β”€ template_manager.py             # Template management
β”‚   └── cache_manager.py                # Cache management
β”œβ”€β”€ scripts/                            # Executable scripts
β”‚   β”œβ”€β”€ create_sorted_group.py          # Create sorted groups
β”‚   β”œβ”€β”€ create_sorted_group_interactive.py  # Interactive workflow
β”‚   └── manage_group.py                 # Group management
β”œβ”€β”€ templates/                          # Sorting templates
β”‚   β”œβ”€β”€ builtin_templates.json          # Built-in templates
β”‚   └── user_templates.json             # User-created templates
β”œβ”€β”€ cache/                              # Cache files (auto-generated)
β”œβ”€β”€ logs/                               # Log files (auto-generated)
β”œβ”€β”€ .env                                # Environment variables
β”œβ”€β”€ .env.example                        # Environment template
β”œβ”€β”€ requirements.txt                    # Python dependencies
└── README.md                           # This file

πŸ› οΈ Development

Module Testing

Each module can be tested independently:

# Config test
python lib/config.py

# Logger test
python lib/logger.py

# Validators test
python lib/validators.py

# Sorters test (sorting algorithms)
python lib/sorters.py

# UI Helpers test
python lib/ui_helpers.py

# StashClient test (requires server connection)
python lib/stash_client.py

DRY_RUN Mode

Set DRY_RUN=true in .env to simulate operations without making actual changes:

DRY_RUN=true

Debugging

Set log level to DEBUG for detailed execution logs:

LOG_LEVEL=DEBUG

Logs are saved to logs/stashsorter.log.

Cache Management

  • Scene data is cached in cache/ directory during operations
  • Cache files are automatically cleaned up on program exit
  • Manual cleanup: Delete files in cache/ directory

πŸ“‹ Sortable Fields

Field Name Description Type
title Scene title String
date Scene date Date
rating100 Rating (0-100) Number
play_count Play count Number
play_duration Total play duration Number
last_played_at Last played timestamp Date
o_counter O counter Number
created_at Created timestamp Date
updated_at Updated timestamp Date
duration Video duration Number
filesize File size Number
framerate Frame rate Number
bitrate Bit rate Number
path File path String
organized Organized flag Boolean
studio.name Studio name String

Nested Field Access:

studio.name
studio.parent_studio.name
files.0.path
files.0.basename
files.0.parent_folder.path
performers.0.name
tags.0.name

βš™οΈ Configuration Options

Environment Variables

Variable Required Default Description
STASH_URL βœ… - StashApp GraphQL endpoint
STASH_API_KEY βœ… - StashApp API key
DRY_RUN ❌ false Test mode (no actual changes)
LOG_LEVEL ❌ INFO Log level (DEBUG, INFO, WARNING, ERROR)
TIMEOUT ❌ 30 API request timeout (seconds)
MAX_RETRIES ❌ 3 Maximum API request retries

πŸ” Troubleshooting

Stash Server Connection Failed

Error: Failed to connect to Stash server

Solutions:

  1. Verify Stash server is running
  2. Check STASH_URL in .env is correct
  3. Verify API Key is valid
  4. Check firewall settings

Invalid API Key Error

Error: Invalid API Key

Solutions:

  1. Generate new API Key in StashApp Settings β†’ Security
  2. Update .env file with new key
  3. Restart the program

No Scenes Found

Error: No scenes found matching criteria

Solutions:

  1. Check if filter conditions are too strict
  2. Try the same filters in StashApp web UI
  3. Set LOG_LEVEL=DEBUG and check query output

Template Not Found

Error: Template not found

Solutions:

  1. Check templates/ directory exists
  2. Verify template files are valid JSON
  3. Re-create templates if corrupted

πŸ“ License

This project is licensed under the MIT License.

🀝 Contributing & Disclaimer

Notice: The entire codebase was generated and orchestrated by Claude Code. As the publisher, I have limited technical knowledge of the internal logic.

Bug reports and feature requests are welcome, but I strongly encourage you to solve them via Fork and Pull Request:

  1. Fork the repository
  2. Create a feature branch
  3. Implement your changes or fixes
  4. Submit a Pull Request

Please note that direct technical support may be limited due to the nature of this project's development.

πŸ“ž Support & Resources

  • GitHub Issues: For reporting critical bugs (resolution depends on community contribution)
  • GraphQL Reference: See Stash GraphQL references

πŸ™ Acknowledgments

  • Claude Code for generating the core logic
  • StashApp Team for the excellent media management platform
  • StashApp Community for their invaluable feedback and suggestions

Made with ❀️ for the StashApp community

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages