Skip to content

Latest commit

 

History

121 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OutSweeper

AI Generation Output Triage for ComfyUI

A fast, keyboard-driven photo triage tool. Open a folder, browse images in a scrollable strip, and sort them into selected or dust sub-folders — all without leaving the keyboard. Pairs naturally with ComfyUI and LM Studio for AI-assisted workflows.

Screenshot

OutSweeper UI

Features

Core triage

  • Keyboard-first navigation across a horizontal thumbnail strip
  • Move photos to __selected (keep) or __dust (reject) with a single keystroke
  • Multi-select with Space / Ctrl+A, then bulk-move the whole selection
  • Undo the last move with Ctrl+Z (in-memory stack)
  • Filter strip by filename in real time
  • Favorites — mark photos with a heart; toggle the strip to show only favorites

Viewing

  • Full-resolution preview panel with mouse-wheel zoom and click-drag pan
  • Three view modes: Fit, 100%, 360° (panoramic scroll)
  • Drag-resizable dividers between the strip, info panel, and preview
  • Lazy-loaded thumbnails (300 × 300 JPEG cache in __thumbnails/, mtime-invalidated)
  • Pagination with configurable page size; jump ±10 pages with Shift+PageDown/Up

Metadata & info panel

  • File info: name, modified/created date, size, dimensions, format
  • EXIF data extraction (date, GPS, ICC profile, PNG text chunks, ComfyUI workflow)
  • ComfyUI workflow details: model, LoRAs, sampler settings, positive prompt, batch size
  • Inline EXIF/metadata editor — edit title, artist, description, document name, copyright, user comment (requires ExifTool)
  • Batch metadata editing across multiple selected files
  • Write AI description to PNG text chunk or JPEG/WebP EXIF UserComment

AI integrations

  • LM Studio — send a free-form text prompt and get a response; copy or forward to ComfyUI
  • Describe image — pass the current photo to a vision model (e.g. LLaVA); save description to file metadata
  • Prompt Composer — build narrative prompts from randomized preset arrays (ambience, character, action, style)
  • One-click "Run LM Studio" / "Run ComfyUI" launcher buttons when the service isn't reachable

ComfyUI integration

  • Send the current image's embedded workflow directly to ComfyUI with Generate
  • Edit any workflow node values before submitting
  • Cartesian-product batch generation: pick multiple LoRA / checkpoint variants, generates all combinations
  • Live ComfyUI queue monitor widget (Running / Waiting / Done)
  • Automatic GPU stats widget: CPU %, RAM %, GPU %, temperature, VRAM %

Job queue

ComfyUI and LM Studio can't both hold VRAM, so every non-interactive operation (Send, Send to front, Improve then send, Guided generation, Outpaint, Upscale) is queued as an internal job and executed one at a time on the backend.

  • Line up as many operations as you like — including ones that mix an LLM step with rendering — and they run in order
  • Before each job: starts ComfyUI / LM Studio if needed, waits for ComfyUI's own queue to drain (or force-clears it), and unloads the other engine to free VRAM
  • Jobs are UI-independent: close the dialog or the whole tab and the work continues
  • Queue widget + manager dialog: live status, drag-to-reorder, cancel one / cancel all, pause
  • Guided generation shows its iterations live and can be re-attached from the queue

File system

  • Background file-system watcher — strip auto-refreshes when files are added or removed
  • Periodic index validation to catch external changes
  • Automatic thumbnail cache cleanup (configurable retention days)
  • Folder switcher: source, __selected, __dust, and the ComfyUI output folder

Custom tools

  • Define shell commands in config.toml that run against the current file (%filename% placeholder)
  • Tools appear as buttons in the info panel

Requirements

Component Version
Python 3.11+ (3.10 with tomli)
Flask ≥ 3.0
Pillow ≥ 10.0
requests ≥ 2.33
psutil ≥ 5.9
nvidia-ml-py ≥ 12.0
websocket-client ≥ 1.6
watchdog ≥ 4.0
ExifTool optional, for metadata editing

Installation

1. Clone

git clone https://github.com/yourname/photo-parser.git
cd photo-parser

2. Install Python dependencies

pip install -r requirements.txt

3. (Optional) ExifTool

Download ExifTool and set its path in config.toml under exiftool_path. Without it, metadata editing is disabled.

4. (Optional) Build the frontend

The static/ directory is pre-built and committed. Rebuild only if you modify the Angular source:

cd frontend
npx ng build

Running

Direct

python app.py <source_folder>

The browser opens automatically at http://localhost:1976.

Without a folder argument

If comfy_output is set in config.toml, calling python app.py with no argument opens that folder directly.

Windows launcher (release build)

run.bat <source_folder>

Development (live reload)

Run the Flask backend and Angular dev server in two terminals:

# Terminal 1
python app.py <source_folder>

# Terminal 2
cd frontend
npx ng serve          # proxies /api → localhost:1976

App is then at http://localhost:4200.


Configuration

Create config.toml next to app.py. All sections and keys are optional.

[permissions]
# Allow changing source folder from the UI
allow_dir_change = true

[defaults]
port                  = 1976
selected_dir_name     = "__selected"
dust_dir_name         = "__dust"

# ComfyUI
comfy_url             = "http://127.0.0.1:8188"
comfy_output          = "C:/path/to/ComfyUI/output"
run_comfy_command     = "C:/path/to/run_nvidia_gpu.bat"

# LM Studio
lmstudio_url          = "http://localhost:1234/v1"
run_lmstudio_command  = "C:/path/to/LM Studio.exe"

# ExifTool
exiftool_path         = "exiftool"          # or full path

# Thumbnail cache: delete thumbnails older than N days
thumb_cache_days      = 3

# Seconds between background index re-validation (null = disabled)
index_validation_interval = 600

[parameters]
extract_exif = true   # show EXIF fields in info panel
extract_gps  = false  # show GPS coordinates
extract_icc  = false  # show ICC colour profile info
extract_png  = true   # show PNG text chunks

[widgets]
gpu_monitor = true    # top-right GPU/CPU stats widget
comfy_queue = true    # top-right ComfyUI queue widget

# Custom tools — %filename% is replaced with the full file path
[tools]
"Split to Four" = "python C:/tools/split_tiles.py %filename%"
"Upscale"       = "python C:/tools/upscale.py %filename%"

Config reference

Key Default Description
defaults.port 1976 HTTP port
defaults.selected_dir_name __selected Sub-folder for kept photos
defaults.dust_dir_name __dust Sub-folder for rejected photos
defaults.comfy_url http://127.0.0.1:8188 ComfyUI API base URL
defaults.comfy_output (empty) ComfyUI output folder; also used as default source if no CLI arg
defaults.run_comfy_command (empty) Shell command to start ComfyUI
defaults.lmstudio_url http://localhost:1234/v1 LM Studio API base URL
defaults.run_lmstudio_command (empty) Shell command to start LM Studio
defaults.exiftool_path exiftool Path to ExifTool binary
defaults.thumb_cache_days 3 Days before stale thumbnails are purged
defaults.index_validation_interval (disabled) Seconds between full index re-checks
parameters.extract_exif true Include EXIF fields in the info panel
parameters.extract_gps false Include GPS coordinates
parameters.extract_icc false Include ICC colour profile
parameters.extract_png true Include PNG text chunks
permissions.allow_dir_change true Show folder-switch button in UI
widgets.gpu_monitor false GPU/CPU stats overlay
widgets.comfy_queue false ComfyUI queue overlay
widgets.lmstudio false LM Studio activity overlay (loaded model, load/prompt progress)
widgets.jobs true Internal job-queue overlay
queue.auto_start_services true Launch ComfyUI / LM Studio on demand when a job needs them
queue.force_clear_comfy false Clear ComfyUI's own queue instead of waiting for it to drain

Keyboard Shortcuts

Navigation

Key Action
Next photo
Previous photo
Move up one strip row
Move down one strip row
Home First photo
End Last photo
Page Down Next page
Page Up Previous page
Shift + Page Down Skip forward 10 pages
Shift + Page Up Skip backward 10 pages

Triage

Key Action
+ Move current photo to __selected
Delete Move current photo to __dust
Space Toggle selection on current photo
Ctrl + A Select all visible photos
Ctrl + Z Undo last move

Other

Key Action
= Switch source folder (opens folder picker)
Ctrl + S Download current photo

Keyboard shortcuts are suppressed when a dialog or text input is focused.


Supported Formats

.png · .jpg · .jpeg · .webp


Project Structure

photo-parser/
├── app.py                  # Entry point: CLI parsing, config loading, server start
├── config.toml             # Local configuration (not committed)
├── requirements.txt
├── server/                 # Flask application package
│   ├── factory.py          # create_app() and all route definitions
│   ├── state.py            # AppState dataclass
│   ├── utils.py            # Image utilities, EXIF extraction, thumbnail cache
│   ├── exiftool.py         # ExifTool integration
│   ├── background.py       # GPU monitor, ComfyUI WebSocket, queue polling
│   ├── events.py           # Server-Sent Events broadcast
│   └── watcher.py          # File-system watcher and index builder
├── frontend/               # Angular 20 source
│   └── src/app/
│       ├── app.ts          # Root component: layout, keyboard, SSE routing
│       ├── components/     # ImageStrip, InfoPanel, PreviewPanel, all dialogs
│       ├── services/       # PhotoService, KeyboardService, ConnectionStateService, …
│       └── models/         # TypeScript interfaces
├── static/                 # Built Angular output (served by Flask)
├── release/                # Windows batch launchers
├── describe.py             # CLI: describe an image with LM Studio
├── gen.py                  # CLI: batch ComfyUI generation from PNG workflows
├── run.py                  # CLI: re-submit PNG workflows with random seeds
└── prompt.py               # CLI: print a single randomised prompt

CLI Utilities

Script Usage Description
describe.py python describe.py <image> [prompt] [model] Describe an image via LM Studio vision API
gen.py python gen.py <folder> Batch ComfyUI generation — reads PNG workflows, randomises prompts and seeds
run.py python run.py <folder> Re-submits PNG workflows with fresh random seeds
prompt.py python prompt.py Prints a single random prompt from preset arrays

License

MIT

About

AI Generation Output Triage for ComfyUI

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages