From 3ecdbb6462d9b48cc6c4f85b9dc1b55133bda5cd Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Fri, 19 Dec 2025 15:12:40 -0500 Subject: [PATCH] feat(wikipedia): implement image selection from Wikipedia with enhanced results display --- .../views/generate_description_view.py | 25 ++- .../components/locations/LocationMedia.svelte | 149 ++++++++++++++---- frontend/src/locales/en.json | 4 +- 3 files changed, 143 insertions(+), 35 deletions(-) diff --git a/backend/server/adventures/views/generate_description_view.py b/backend/server/adventures/views/generate_description_view.py index b54e3a03..28719608 100644 --- a/backend/server/adventures/views/generate_description_view.py +++ b/backend/server/adventures/views/generate_description_view.py @@ -91,8 +91,13 @@ class GenerateDescription(viewsets.ViewSet): try: candidates = self.get_candidate_pages(name, lang) + found_images = [] for candidate in candidates: + # Stop after finding 5 valid images + if len(found_images) >= 8: + break + page_data = self.fetch_page( lang=lang, candidate=candidate, @@ -113,13 +118,29 @@ class GenerateDescription(viewsets.ViewSet): # Try original image first original_image = page_data.get('original') if original_image and self.is_valid_image(original_image.get('source')): - return Response(original_image) + found_images.append({ + 'source': original_image.get('source'), + 'width': original_image.get('width'), + 'height': original_image.get('height'), + 'title': page_data.get('title'), + 'type': 'original' + }) + continue # Fall back to thumbnail thumbnail_image = page_data.get('thumbnail') if thumbnail_image and self.is_valid_image(thumbnail_image.get('source')): - return Response(thumbnail_image) + found_images.append({ + 'source': thumbnail_image.get('source'), + 'width': thumbnail_image.get('width'), + 'height': thumbnail_image.get('height'), + 'title': page_data.get('title'), + 'type': 'thumbnail' + }) + if found_images: + return Response({"images": found_images}) + return Response({"error": "No image found"}, status=404) except requests.exceptions.RequestException: diff --git a/frontend/src/lib/components/locations/LocationMedia.svelte b/frontend/src/lib/components/locations/LocationMedia.svelte index 5b4fb254..346e3ba2 100644 --- a/frontend/src/lib/components/locations/LocationMedia.svelte +++ b/frontend/src/lib/components/locations/LocationMedia.svelte @@ -75,6 +75,15 @@ let wandererFetchedTrails: WandererTrail[] = []; + // Wikipedia image selection + let wikiImageResults: Array<{ + source: string; + width: number; + height: number; + title: string; + type: string; + }> = []; + // Allowed file types for attachments const allowedFileTypes = [ '.gpx', @@ -221,14 +230,29 @@ const res = await fetch(`/api/generate/img/?name=${encodeURIComponent(imageSearch)}`); const data = await res.json(); - if (!res.ok || !data.source) { + if (!res.ok || !data.images || data.images.length === 0) { wikiImageError = $t('adventures.image_fetch_failed'); return; } - const blob = await fetchImageFromUrl(data.source); + // Store results to display inline + wikiImageResults = data.images; + } catch (error) { + wikiImageError = $t('adventures.wiki_image_error'); + addToast('error', $t('adventures.image_upload_error')); + } finally { + isLoading = false; + } + } + + async function selectWikiImage(imageUrl: string) { + isLoading = true; + + try { + const blob = await fetchImageFromUrl(imageUrl); if (!blob) { wikiImageError = $t('adventures.image_fetch_failed'); + isLoading = false; return; } @@ -238,7 +262,7 @@ if (newImage) { updateImagesList(newImage); addToast('success', $t('adventures.image_upload_success')); - imageSearch = ''; + // Keep results open to allow adding multiple images } else { throw new Error('Upload failed'); } @@ -750,35 +774,6 @@ {/if} - -
-

- {$t('adventures.wikipedia')} -

-
- - -
- {#if wikiImageError} -
- {wikiImageError} -
- {/if} -
- {#if immichIntegration}
@@ -797,6 +792,96 @@ {/if}
+ +
+

+ {$t('adventures.wikipedia')} +

+
+ + +
+ {#if wikiImageError} +
+ {wikiImageError} +
+ {/if} + + + {#if wikiImageResults.length > 0} +
+
+ + {$t('adventures.wiki_results_found', { + values: { count: wikiImageResults.length, query: imageSearch } + })} + + +
+
+ {#each wikiImageResults as result (result.source)} + + {/each} +
+
+ {/if} +
+ {#if images.length > 0}
Current Images
diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index b829fd94..298bad8e 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -479,7 +479,9 @@ "activity_breakdown_by_category": "Activity Breakdown by Category", "dates_not_saved": "Visit Not Added Yet", "dates_not_saved_description": "Click add visit to save", - "link_copied": "Link Copied" + "link_copied": "Link Copied", + "wiki_results_found": "Wikipedia Results", + "select": "Select" }, "worldtravel": { "country_list": "Country List",