| name | find-photo |
| description | find and assign copyright-free photos to world66 content pages. invoke when the user asks to find, search, or add images/photos to destinations, cities, or content pages |
| argument-hint | <content-path or scope description> |
Find copyright-free photos for World66 content pages using Wikimedia Commons and Flickr. If no argument is provided, ask the user which page or scope they want photos for.
Steps
Single page
-
Determine the content path from the user's request. Example: "find a photo for Hamburg" → europe/germany/hamburg. If unsure of the exact path, look in the content/ directory.
-
Search for candidates without AI classification:
python tools/find_photo.py --no-classify <content-path>
This outputs JSON to stdout with candidate thumbnails. Status messages go to stderr.
-
Review the candidates. Parse the JSON output. If candidates is non-empty:
- Read each thumbnail image file from the
thumb_path fields
- Pick the best photo based on relevance to the destination, visual quality, and how well it represents the place
- Avoid extreme panoramas or very thin crops; hero images should usually have a natural landscape-photo aspect ratio, roughly between 1.2:1 and 2.5:1, so they crop well in the site layout
- Note the chosen candidate's
index
-
Save the chosen photo:
python tools/find_photo.py --select-meta '{"url":"...","source":"...","license":"...","attribution":"...","source_page":"..."}' <content-path>
Pass the full candidate metadata as JSON. The script downloads the full-resolution image, resizes it, and updates the markdown frontmatter.
-
If no candidates found (empty candidates array), tell the user no suitable photos were found.
-
If you cannot view images (no vision capability), skip --no-classify and run:
python tools/find_photo.py <content-path>
This uses an installed AI CLI (gemini/codex/cline) to classify automatically.
Batch (scoped)
-
Determine the scope from the user's request. Example: "all cities in the Netherlands" → prefix europe/netherlands, type location.
-
Preview first with dry-run:
python tools/find_photo.py --batch --prefix <prefix> --type <type> --dry-run
Show the user how many pages will be processed. Get confirmation before proceeding.
-
For small scopes (< ~10 pages): loop single-page --no-classify calls so you can review each photo yourself. Process one at a time.
-
For large scopes (10+ pages): use the batch mode with CLI adapter classification:
python tools/find_photo.py --batch --prefix <prefix> --type <type>
Or use --no-classify --output candidates.json to get all candidates in a file:
python tools/find_photo.py --batch --prefix <prefix> --type <type> --no-classify --output candidates.json
Then review and --select-meta for each page.
-
Report results — summarize how many pages were processed, how many got photos, and any that were skipped.
Rules
- Never use
--force unless the user explicitly asks to replace existing images.
- Always run
--dry-run before large batch operations to preview the scope.
FLICKR_API_KEY in .env is optional. Without it, only Wikimedia Commons is searched.
- Don't process hundreds of pages without user confirmation — check the count first.
- Exit codes: 0 = success/candidates found, 1 = no suitable photo found, 2 = error.
- Pages that already have an
image field in frontmatter are automatically skipped (unless --force).
- The
--type flag defaults to location. Other options: section, poi.