{"id":30385322,"url":"https://github.com/funkatron/prompt-image-organizer","last_synced_at":"2025-08-21T02:13:59.677Z","repository":{"id":304252711,"uuid":"1018250000","full_name":"funkatron/prompt-image-organizer","owner":"funkatron","description":"Organize AI-generated images into session folders by prompt similarity and creation time. Smart clustering, dry-run mode, and fast multi-threaded operations.","archived":false,"fork":false,"pushed_at":"2025-07-11T22:14:59.000Z","size":41,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-16T12:34:16.460Z","etag":null,"topics":["ai","automation","cli","image-processing","prompt-engineering","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/funkatron.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-11T21:56:50.000Z","updated_at":"2025-07-11T22:12:40.000Z","dependencies_parsed_at":"2025-07-12T00:26:35.514Z","dependency_job_id":null,"html_url":"https://github.com/funkatron/prompt-image-organizer","commit_stats":null,"previous_names":["funkatron/prompt-image-organizer"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/funkatron/prompt-image-organizer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkatron%2Fprompt-image-organizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkatron%2Fprompt-image-organizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkatron%2Fprompt-image-organizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkatron%2Fprompt-image-organizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/funkatron","download_url":"https://codeload.github.com/funkatron/prompt-image-organizer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkatron%2Fprompt-image-organizer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271415496,"owners_count":24755639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-21T02:00:08.990Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","automation","cli","image-processing","prompt-engineering","python"],"created_at":"2025-08-21T02:13:58.037Z","updated_at":"2025-08-21T02:13:59.667Z","avatar_url":"https://github.com/funkatron.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Prompt Image Organizer\n\nOrganize AI-generated images into session folders based on their prompts and creation time.\n\n## What it does\n\nThis tool helps you organize AI-generated images (like those from Draw Things, Stable Diffusion, etc.) by grouping them into session folders based on:\n\n- **Time proximity**: Images created within a specified time gap are grouped into the same session\n- **Prompt similarity**: Images with similar prompts are clustered into the same session\n- **Creation order**: Maintains chronological organization within sessions\n\n## Features\n\n- **Smart clustering**: Groups images by prompt similarity and time gaps into session folders\n- **Flexible configuration**: Adjustable time gaps and similarity thresholds\n- **Safe operations**: Dry-run mode to preview changes before making them\n- **Progress tracking**: Visual progress bars for long operations\n- **Concurrent processing**: Multi-threaded file operations for speed\n\n## Installation\n\n### Development Setup\n\n```bash\n# Clone the repository\ngit clone \u003crepository-url\u003e\ncd prompt-image-organizer\n\n# Install dependencies with uv\nuv sync\n\n# Install package in development mode\nuv pip install -e .\n```\n\n### From PyPI (when published)\n\n```bash\npip install prompt-image-organizer\n```\n\n## Usage\n\n### Command Line Interface\n\n```bash\n# Preview what would be organized (dry run)\nuv run prompt-image-organizer ./source-images ./session-folders\n\n# Actually organize the images into session folders\nuv run prompt-image-organizer ./source-images ./session-folders -x\n\n# Or if installed globally\nprompt-image-organizer ./source-images ./session-folders -x\n```\n\n### Advanced options\n\n```bash\n# Custom time gap (45 minutes) and similarity threshold (0.9)\nuv run prompt-image-organizer ./imgs ./out --gap 45 --sim 0.9 -x\n\n# Limit cluster size to 100 images per session folder\nuv run prompt-image-organizer ./imgs ./out --limit 100 -x\n\n# Use more worker threads for faster processing\nuv run prompt-image-organizer ./imgs ./out --workers 12 -x\n```\n\n### Environment variables\n\nYou can also configure via environment variables:\n\n```bash\nexport SRC_DIR=\"./source-images\"\nexport DST_DIR=\"./session-folders\"\nexport SESSION_GAP_MINUTES=60\nexport PROMPT_SIMILARITY=0.8\nexport SESSION_CLUSTER_LIMIT=100\nexport SESSION_WORKERS=8\n\nuv run prompt-image-organizer -x\n```\n\n### Python API\n\n```python\nfrom prompt_image_organizer import (\n    scan_files,\n    group_by_time,\n    cluster_prompts,\n    process_clusters,\n    print_summary\n)\nfrom datetime import timedelta\n\n# Scan files\nfile_data = scan_files(\"./images\")\n\n# Group by time (60 minute gaps)\nbatches = group_by_time(file_data, timedelta(minutes=60))\n\n# Process with custom config\nconfig = {\n    \"src_dir\": \"./images\",\n    \"dst_dir\": \"./sessions\",\n    \"gap\": timedelta(minutes=60),\n    \"sim_thresh\": 0.8,\n    \"cluster_size_limit\": None,\n    \"dry_run\": True,\n    \"workers\": 8\n}\n\nsession_count, total_files, move_errors = process_clusters(batches, config)\nprint_summary(session_count, total_files, move_errors, config[\"dry_run\"])\n```\n\n## Configuration\n\n- **`--gap MIN`**: Maximum time gap in minutes to group images (default: 60)\n- **`--sim F`**: Prompt similarity threshold 0-1 (default: 0.8)\n- **`--limit N`**: Maximum images per session folder (default: unlimited)\n- **`--workers N`**: Number of concurrent file operations (default: 8)\n- **`-x`**: Actually move files (default: dry run)\n\n## How it works\n\n1. **Scans** your source directory for image files (.png, .jpg, .jpeg, .webp)\n2. **Extracts** prompts from filenames (removes numbering suffixes)\n3. **Groups** images by time gaps into batches\n4. **Clusters** each batch by prompt similarity\n5. **Creates** session folders with descriptive names\n6. **Moves** files into organized session structure\n\n## Session folder naming\n\nSession folders are named using the pattern:\n```\nsession_YYYYMMDD_HHMM_prompt-name/\n```\n\nExample: `session_20241201_1430_a-cat-sitting-on-a-chair/`\n\n## File naming conventions\n\nThe tool expects image files with prompts in the filename. It extracts the prompt by removing numbering suffixes:\n\n- `my_prompt_1.png` → prompt: `my_prompt`\n- `another_prompt_2.jpg` → prompt: `another_prompt`\n- `complex_prompt_with_spaces_3.webp` → prompt: `complex_prompt_with_spaces`\n\n## Requirements\n\n- Python 3.12+\n- tqdm (for progress bars)\n\n## Development\n\n### Running Tests\n\n```bash\n# Run all tests with unittest\nuv run python -m unittest discover tests -v\n\n# Run tests with pytest (if installed)\nuv run pytest tests/ -v\n\n# Run tests with coverage\nuv run pytest --cov=src/prompt_image_organizer tests/\n```\n\n### Code Quality\n\n```bash\n# Format code with Black\nuv run black src/ tests/\n\n# Lint with Flake8\nuv run flake8 src/ tests/\n\n# Type checking with mypy\nuv run mypy src/\n```\n\n### Test Structure\n\n- **`tests/test_utils.py`**: Unit tests for utility functions\n- **`tests/test_integration.py`**: Integration tests for full workflow\n- **`tests/test_cli.py`**: CLI and command line interface tests\n- **`tests/conftest.py`**: Pytest fixtures and configuration\n\n### Test Coverage\n\nThe test suite covers:\n- ✅ Utility functions (sanitize_for_folder, extract_prompt, similar, etc.)\n- ✅ File operations (get_image_files, move_file_worker)\n- ✅ Time-based grouping (group_by_time)\n- ✅ Prompt clustering (cluster_prompts)\n- ✅ Configuration parsing (parse_config)\n- ✅ CLI functionality (argument parsing, help text)\n- ✅ Error handling (invalid inputs, permission errors)\n- ✅ Edge cases (empty directories, no images)\n- ✅ Full workflow (dry run and actual file movement)\n\n## Project Structure\n\n```\nprompt-image-organizer/\n├── src/prompt_image_organizer/\n│   ├── __init__.py          # Package entry point\n│   ├── __main__.py          # CLI entry point for python -m\n│   ├── core.py              # Core functionality\n│   └── cli.py               # Command-line interface\n├── tests/                   # Test suite\n├── examples/                # Usage examples\n├── pyproject.toml          # Project configuration\n└── README.md               # This file\n```\n\n## License\n\nMIT License\n\nCopyright Edward Finkler (c) 2025\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunkatron%2Fprompt-image-organizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffunkatron%2Fprompt-image-organizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunkatron%2Fprompt-image-organizer/lists"}