Skip to main content

Wallpaper collection management CLI tool

Project description

Schenesort v2.4.0

Collage example

A cli tool for managing wallpaper collections with model generated metadata, sweet tui, and sql metadata querying.

schenesort takes a directory of random wallpapers, with random filenames, and uses olama with a decent vision model to:

  • look at each wallpaper
  • rename the wallpaper to something sensible
  • drop a XMP sidecar with metadata about the file

Once you have a collection of wallpapers re-named with metadata sidecars, run the indexer over it to create a sqlitedb that can be queried to retrieve suggestions based on tags, colours, names and the like. Then use get to get a wallpaper path feh $(schenesort get -1 -p) or hyprctl hyprpaper wallpaper "eDP-1,$(schenesort get -1 -p)"

Browse example - Autumn

Installation

uv tool install schenesort

For development:

git clone https://github.com/sthysel/schenesort.git
cd schenesort
uv sync

Quick Start

To generate metadata you need a olama server serving llava nearby, it takes a minute to set one up see ollama setup.

# Generate metadata for images
schenesort metadata generate ~/wallpapers -r

# Index the collection
schenesort index ~/wallpapers

# Generate thumbnails for gallery
schenesort thumbnail ~/wallpapers -r

# Browse with gallery (thumbnail grid with filters)
schenesort gallery

# Browse single images with TUI
schenesort browse ~/wallpapers

# Query wallpapers
schenesort get --mood peaceful --screen 4K
schenesort get -1 -p | xargs feh  # random wallpaper

Commands

Command Description
browse Terminal UI browser with image preview and metadata
gallery Thumbnail grid browser with filters
thumbnail Generate thumbnail cache for gallery
index Build SQLite index for fast querying
get Query wallpapers by metadata attributes
stats Show collection statistics from index
config Show or create configuration file
sanitise Rename files to Unix-friendly format
validate Check image extensions match file content
cleanup Delete orphaned XMP sidecars
info Show collection file statistics
describe AI-rename images based on content (Ollama)
models List available Ollama models
collage Create a collage grid from matching wallpapers
metadata show Display XMP sidecar metadata
metadata set Manually set metadata fields
metadata generate Generate metadata with AI (Ollama)
metadata update-dimensions Add image dimensions to existing sidecars
metadata embed Embed sidecar data into image files

Terminal UI Browser

Browse your wallpaper collection with image preview and metadata display:

schenesort browse ~/wallpapers
schenesort browse ~/wallpapers -r  # recursive
schenesort browse                  # uses paths.wallpaper from config
schenesort get --mood peaceful -b  # browse query results

Browse example - Autumn

Browse example - Stallman

Keyboard shortcuts:

Key Action
j / Down Next image
k / Up Previous image
g / Home First image
G / End Last image
+ / - Zoom in/out
q Quit

The TUI uses textual-image for rendering, which auto-detects terminal graphics support (Sixel, iTerm2, Kitty).

Gallery Browser

Browse your indexed collection with a thumbnail grid and filter panel:

# Open gallery browser
schenesort gallery

# Pre-filter results
schenesort gallery --mood peaceful
schenesort gallery --tag nature --style photography

The gallery requires an indexed collection (schenesort index) and cached thumbnails for fast loading.

Generate Thumbnails

# Generate thumbnails for a directory
schenesort thumbnail ~/wallpapers

# Recursive with progress bar
schenesort thumbnail ~/wallpapers -r

# Force regenerate all thumbnails
schenesort thumbnail ~/wallpapers --force

# Clear thumbnail cache
schenesort thumbnail ~/wallpapers --clear

Thumbnails are cached at ~/.cache/schenesort/thumbnails/ (320x200 JPEG).

Gallery keyboard shortcuts:

Key Action
j / Down Move down
k / Up Move up
h / Left Move left
l / Right Move right
g / Home First image
G / End Last image
Enter Open detail view
Tab Switch panel
Escape Clear filters
r Refresh
q / Ctrl+C Quit

Detail view shortcuts:

Key Action
j / Down Next image
k / Up Previous image
Escape / q Back to grid

Collection Indexing and Querying

Build a SQLite index for fast querying across your entire collection:

# Build/update the index
schenesort index ~/wallpapers
schenesort index ~/wallpapers --rebuild   # rebuild from scratch
schenesort index ~/wallpapers --prune     # remove deleted files

# Query wallpapers
schenesort get --tag cyberpunk
schenesort get --mood peaceful --style photography
schenesort get --screen 4K --subject landscape
schenesort get --color blue --time sunset
schenesort get --min-width 3840
schenesort get -q "mountain"              # text search

# Random selection
schenesort get --random -n 10             # 10 random wallpapers
schenesort get -1                         # single random wallpaper
schenesort get -1 --mood dramatic         # random with filter

# Browse results in TUI
schenesort get --mood peaceful --browse   # open matches in browser
schenesort get --style photography -b     # short form

# For scripting (paths only)
schenesort get -1 -p                      # just the path
feh $(schenesort get -1 -p)               # set random wallpaper
hyprctl hyprpaper wallpaper "eDP-1,$(schenesort get -1 -p)"

# View collection stats
schenesort stats

The database is stored at $XDG_DATA_HOME/schenesort/index.db (default: ~/.local/share/schenesort/index.db).

Collage Generation

Create a collage grid (up to 4x4) from wallpapers matching query criteria:

# Create a 2x2 collage (default)
schenesort collage output.png --mood peaceful

# Create a 4x4 collage of landscape images
schenesort collage wall.png --subject landscape --cols 4 --rows 4

# Custom tile size (default: 480x270)
schenesort collage collage.png --tile-width 640 --tile-height 360

# Combine filters
schenesort collage night_cities.png --time night --subject urban --cols 3 --rows 2

schenesort collage landscape.png --cols 4 --rows 4 --tile-width 640 --tile-height 360 --tag landscape

Collage example

Option Description Default
--cols Number of columns (1-4) 2
--rows Number of rows (1-4) 2
--tile-width Width of each tile in pixels 480
--tile-height Height of each tile in pixels 270
--random Select images randomly True

All get query filters are supported: --tag, --mood, --color, --style, --subject, --time, --screen, --min-width, --min-height, --search.

Metadata Management

Store metadata in XMP sidecar files (.xmp) alongside images without modifying the original files.

Metadata Fields

Field Description
description Short description (used for filenames)
scene Detailed scene description
tags Keywords/tags
mood Visual mood (peaceful, dramatic, mysterious, etc.)
style Art style (photography, digital art, illustration, etc.)
colors Dominant colors
time_of_day Time depicted (day, night, sunset, etc.)
subject Primary subject (landscape, urban, nature, etc.)
width / height Image dimensions in pixels
recommended_screen Best screen size (4K, 1440p, 1080p, etc.)
source Source URL or info
ai_model Model used for metadata generation

Generate Metadata using ollama

# Preview what would be generated
schenesort metadata generate ~/wallpapers --dry-run

# Generate metadata and rename files
schenesort metadata generate ~/wallpapers -m llava

# Generate without renaming
schenesort metadata generate ~/wallpapers --no-rename

# Overwrite existing metadata
schenesort metadata generate ~/wallpapers --overwrite

# Use remote Ollama server
schenesort metadata generate ~/wallpapers --host http://server:11434

Update Dimensions Only

Add dimensions to existing sidecars without re-running AI inference:

schenesort metadata update-dimensions ~/wallpapers -r

Manual Metadata

# Show metadata
schenesort metadata show image.jpg

# Set fields manually
schenesort metadata set image.jpg -d "Mountain sunset landscape"
schenesort metadata set image.jpg -t "nature,sunset,mountains"
schenesort metadata set image.jpg -a "peaceful"  # add tag
schenesort metadata set image.jpg -s "https://unsplash.com/..."

Embed into Image Files

Write metadata directly into images (requires exiftool):

schenesort metadata embed ~/wallpapers -r

Filename Sanitation

The sanitise command makes filenames Unix-friendly:

schenesort sanitise ~/wallpapers --dry-run
schenesort sanitise ~/wallpapers -r
Rule Example
Lowercase HelloWorld.JPGhelloworld.jpg
Spaces → underscore my file.jpgmy_file.jpg
Remove punctuation file(1)!.jpgfile1.jpg
Collapse underscores a___b.jpga_b.jpg
Strip leading/trailing _- _file_.jpgfile.jpg

Cleanup Orphaned Sidecars

Delete XMP sidecar files that have no corresponding image:

schenesort cleanup ~/wallpapers --dry-run
schenesort cleanup ~/wallpapers -r

Configuration

Schenesort follows XDG Base Directory spec:

  • Config: $XDG_CONFIG_HOME/schenesort/config.toml (default: ~/.config/schenesort/config.toml)
  • Data: $XDG_DATA_HOME/schenesort/index.db (default: ~/.local/share/schenesort/index.db)
# Show current config
schenesort config

# Create default config file
schenesort config --create

Config file format:

[ollama]
# Ollama server URL (leave empty for localhost:11434)
host = "http://server:11434"

# Default vision model
model = "llava:13b"

[paths]
# Default wallpaper collection path
wallpaper = "~/wallpapers"

Command-line options override config file settings.

Ollama Setup (Arch Linux)

# Install
yay -S ollama ollama-cuda  # for NVIDIA GPU

# Start service
sudo systemctl enable --now ollama

# Pull a vision model
ollama pull llava           # ~4GB
ollama pull llava:13b       # ~8GB, better quality

# List available models
schenesort models

Yazi Plugin

A Yazi previewer plugin that displays XMP metadata alongside image previews.

Installation

# Copy plugin
mkdir -p ~/.config/yazi/plugins/schenesort.yazi
cp schenesort.yazi/main.lua ~/.config/yazi/plugins/schenesort.yazi/

# Install exiftool config for custom namespace
mkdir -p ~/.config/ExifTool
cp schenesort.yazi/schenesort.config ~/.config/ExifTool/

# Install exiftool
sudo pacman -S perl-image-exiftool  # Arch

Add to ~/.config/yazi/yazi.toml:

[plugin]
prepend_previewers = [
    { mime = "image/*", run = "schenesort" },
]

See schenesort.yazi/README.md for details.

XMP Sidecar Format

~/wallpapers/
├── mountain_sunset.jpg
├── mountain_sunset.jpg.xmp   ← metadata stored here
├── cyberpunk_city.png
└── cyberpunk_city.png.xmp

Metadata is stored in standard XMP format, compatible with digiKam, darktable, and Lightroom.

Screen Size Recommendations

Images are tagged with recommended screen sizes based on resolution:

Screen Resolution
8K 7680x4320
5K 5120x2880
4K 3840x2160
Ultrawide 4K 5120x2160
Ultrawide 1440p 3440x1440
1440p 2560x1440
1080p 1920x1080
720p 1280x720

An image is recommended for a screen size if it can cover the screen without upscaling.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

schenesort-2.4.0.tar.gz (36.3 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

schenesort-2.4.0-py3-none-any.whl (38.3 kB view details)

Uploaded Python 3

File details

Details for the file schenesort-2.4.0.tar.gz.

File metadata

  • Download URL: schenesort-2.4.0.tar.gz
  • Upload date:
  • Size: 36.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for schenesort-2.4.0.tar.gz
Algorithm Hash digest
SHA256 d20cd58a79990cee521fbac308098aa0502a2f13f0b5b0f1e45089a06ccf9a28
MD5 2851abc531a85fb2741a68fe950124bf
BLAKE2b-256 41c418df09b94da7641124f4bfc5635307d5c7989b9177ac3b694c3059664e7a

See more details on using hashes here.

Provenance

The following attestation bundles were made for schenesort-2.4.0.tar.gz:

Publisher: publish.yml on sthysel/schenesort

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file schenesort-2.4.0-py3-none-any.whl.

File metadata

  • Download URL: schenesort-2.4.0-py3-none-any.whl
  • Upload date:
  • Size: 38.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for schenesort-2.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 968fce2e534b308af80a88cbf496e258bff01bf65b8dadcf41bb812bdab0f8e3
MD5 6dd1747c24b0d76819e709afb9235d0d
BLAKE2b-256 8a2c885cbe3664cd2da9160b6d14e242f551d5baa77444c8fdc01e619914f872

See more details on using hashes here.

Provenance

The following attestation bundles were made for schenesort-2.4.0-py3-none-any.whl:

Publisher: publish.yml on sthysel/schenesort

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page