Wallpaper collection management CLI tool
Project description
Schenesort v2.3.0
A CLI tool for managing wallpaper collections with model generated metadata, terminal UI browsing, and SQLite-based 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)"
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
# Browse with TUI
schenesort browse ~/wallpapers
# Index the collection
schenesort index ~/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 |
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
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).
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
| 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.JPG → helloworld.jpg |
| Spaces → underscore | my file.jpg → my_file.jpg |
| Remove punctuation | file(1)!.jpg → file1.jpg |
| Collapse underscores | a___b.jpg → a_b.jpg |
Strip leading/trailing _- |
_file_.jpg → file.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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file schenesort-2.3.0.tar.gz.
File metadata
- Download URL: schenesort-2.3.0.tar.gz
- Upload date:
- Size: 22.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82c80b9ddc8745a6055c5f8fc702dfdbfb9ba2148151f83b8c47cc8efa0d6646
|
|
| MD5 |
cf6cce819f641df038b16a2c7f5176d8
|
|
| BLAKE2b-256 |
9f6dabfff03b70805642934380ae70da6d7cfb6b1b88eaa756aebac3b0d7e2e2
|
Provenance
The following attestation bundles were made for schenesort-2.3.0.tar.gz:
Publisher:
publish.yml on sthysel/schenesort
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
schenesort-2.3.0.tar.gz -
Subject digest:
82c80b9ddc8745a6055c5f8fc702dfdbfb9ba2148151f83b8c47cc8efa0d6646 - Sigstore transparency entry: 910950981
- Sigstore integration time:
-
Permalink:
sthysel/schenesort@9797b0ea2a66b92ff7421b14cb1435445509cee9 -
Branch / Tag:
refs/tags/v2.3.0 - Owner: https://github.com/sthysel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9797b0ea2a66b92ff7421b14cb1435445509cee9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file schenesort-2.3.0-py3-none-any.whl.
File metadata
- Download URL: schenesort-2.3.0-py3-none-any.whl
- Upload date:
- Size: 28.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bf62dc631bd15915ca1a25cb9de6ff44369a4e8786a83b09f59e2b02a8eb05c
|
|
| MD5 |
08d65ad9bd322edbb700c39fc9d37bf2
|
|
| BLAKE2b-256 |
c2819824f37bcce38300bc5fee590de2e3ae1515ee4b02b14714d7c155ac5cdb
|
Provenance
The following attestation bundles were made for schenesort-2.3.0-py3-none-any.whl:
Publisher:
publish.yml on sthysel/schenesort
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
schenesort-2.3.0-py3-none-any.whl -
Subject digest:
8bf62dc631bd15915ca1a25cb9de6ff44369a4e8786a83b09f59e2b02a8eb05c - Sigstore transparency entry: 910950999
- Sigstore integration time:
-
Permalink:
sthysel/schenesort@9797b0ea2a66b92ff7421b14cb1435445509cee9 -
Branch / Tag:
refs/tags/v2.3.0 - Owner: https://github.com/sthysel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9797b0ea2a66b92ff7421b14cb1435445509cee9 -
Trigger Event:
push
-
Statement type: