| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import { Mapillary } from "./Mapillary" | 
					
						
							|  |  |  | import { WikimediaImageProvider } from "./WikimediaImageProvider" | 
					
						
							|  |  |  | import { Imgur } from "./Imgur" | 
					
						
							|  |  |  | import GenericImageProvider from "./GenericImageProvider" | 
					
						
							| 
									
										
										
										
											2024-10-08 12:41:14 +02:00
										 |  |  | import { ImmutableStore, Store, UIEventSource } from "../UIEventSource" | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import ImageProvider, { ProvidedImage } from "./ImageProvider" | 
					
						
							|  |  |  | import { WikidataImageProvider } from "./WikidataImageProvider" | 
					
						
							| 
									
										
										
										
											2024-09-26 19:15:20 +02:00
										 |  |  | import Panoramax from "./Panoramax" | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  | import { Utils } from "../../Utils" | 
					
						
							| 
									
										
										
										
											2021-06-22 14:21:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * A generic 'from the interwebz' image picker, without attribution | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-09-09 00:05:51 +02:00
										 |  |  | export default class AllImageProviders { | 
					
						
							| 
									
										
										
										
											2024-02-21 00:13:11 +01:00
										 |  |  |     private static dontLoadFromPrefixes = ["https://photos.app.goo.gl/"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-27 12:59:38 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * The 'genericImageProvider' is a fallback that scans various other tags for tags, unless the URL starts with one of the given prefixes | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static genericImageProvider = new GenericImageProvider([ | 
					
						
							|  |  |  |         ...Imgur.defaultValuePrefix, | 
					
						
							|  |  |  |         ...WikimediaImageProvider.commonsPrefixes, | 
					
						
							|  |  |  |         ...Mapillary.valuePrefixes, | 
					
						
							|  |  |  |         ...AllImageProviders.dontLoadFromPrefixes, | 
					
						
							|  |  |  |         "Category:", | 
					
						
							|  |  |  |     ]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private static ImageAttributionSource: ImageProvider[] = [ | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  |         Imgur.singleton, | 
					
						
							|  |  |  |         Mapillary.singleton, | 
					
						
							|  |  |  |         WikidataImageProvider.singleton, | 
					
						
							|  |  |  |         WikimediaImageProvider.singleton, | 
					
						
							| 
									
										
										
										
											2024-09-26 19:15:20 +02:00
										 |  |  |         Panoramax.singleton, | 
					
						
							| 
									
										
										
										
											2024-08-09 16:55:08 +02:00
										 |  |  |         AllImageProviders.genericImageProvider, | 
					
						
							| 
									
										
										
										
											2021-10-06 17:48:07 +02:00
										 |  |  |     ] | 
					
						
							| 
									
										
										
										
											2023-09-27 22:21:35 +02:00
										 |  |  |     public static apiUrls: string[] = [].concat( | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |         ...AllImageProviders.ImageAttributionSource.map((src) => src.apiUrls()) | 
					
						
							| 
									
										
										
										
											2023-09-27 22:21:35 +02:00
										 |  |  |     ) | 
					
						
							|  |  |  |     public static defaultKeys = [].concat( | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |         AllImageProviders.ImageAttributionSource.map((provider) => provider.defaultKeyPrefixes) | 
					
						
							| 
									
										
										
										
											2023-09-27 22:21:35 +02:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2022-05-06 12:41:24 +02:00
										 |  |  |     private static providersByName = { | 
					
						
							|  |  |  |         imgur: Imgur.singleton, | 
					
						
							|  |  |  |         mapillary: Mapillary.singleton, | 
					
						
							|  |  |  |         wikidata: WikidataImageProvider.singleton, | 
					
						
							|  |  |  |         wikimedia: WikimediaImageProvider.singleton, | 
					
						
							| 
									
										
										
										
											2024-10-08 12:41:14 +02:00
										 |  |  |         panoramax: Panoramax.singleton, | 
					
						
							| 
									
										
										
										
											2022-05-06 12:41:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-27 22:21:35 +02:00
										 |  |  |     public static byName(name: string) { | 
					
						
							|  |  |  |         return AllImageProviders.providersByName[name.toLowerCase()] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-27 12:59:38 +02:00
										 |  |  |     public static async selectBestProvider(key: string, value: string): Promise<ImageProvider> { | 
					
						
							|  |  |  |         for (const imageProvider of AllImageProviders.ImageAttributionSource) { | 
					
						
							| 
									
										
										
										
											2024-08-09 16:55:08 +02:00
										 |  |  |             try { | 
					
						
							|  |  |  |                 const extracted = await Promise.all(await imageProvider.ExtractUrls(key, value)) | 
					
						
							|  |  |  |                 if (extracted?.length > 0) { | 
					
						
							|  |  |  |                     return imageProvider | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } catch (e) { | 
					
						
							| 
									
										
										
										
											2024-07-27 12:59:38 +02:00
										 |  |  |                 console.warn("Provider gave an error while trying to determine a match:", e) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return AllImageProviders.genericImageProvider | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-05 00:18:16 +01:00
										 |  |  |     private static readonly _cachedImageStores: Record<string, Store<ProvidedImage[]>> = {} | 
					
						
							| 
									
										
										
										
											2024-09-26 19:15:20 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2024-11-14 18:25:27 +01:00
										 |  |  |      * Tries to extract all image data for this image. Cached on tags?.data?.id | 
					
						
							| 
									
										
										
										
											2024-09-26 19:15:20 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |     public static LoadImagesFor( | 
					
						
							|  |  |  |         tags: Store<Record<string, string>>, | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |         tagKey?: string[] | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |     ): Store<ProvidedImage[]> { | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  |         if (tags?.data?.id === undefined) { | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  |             return undefined | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-11-05 00:18:16 +01:00
										 |  |  |         const id = tags?.data?.id | 
					
						
							| 
									
										
										
										
											2024-11-14 18:25:27 +01:00
										 |  |  |         const cachekey = id + (tagKey?.join(";") ?? "") | 
					
						
							|  |  |  |         if (this._cachedImageStores[cachekey]) { | 
					
						
							|  |  |  |             return this._cachedImageStores[cachekey] | 
					
						
							| 
									
										
										
										
											2024-11-05 00:18:16 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const source = new UIEventSource([]) | 
					
						
							| 
									
										
										
										
											2024-07-27 12:59:38 +02:00
										 |  |  |         const allSources: Store<ProvidedImage[]>[] = [] | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  |         for (const imageProvider of AllImageProviders.ImageAttributionSource) { | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  |             /* | 
					
						
							|  |  |  |                 By default, 'GetRelevantUrls' uses the defaultKeyPrefixes. | 
					
						
							|  |  |  |                 However, we override them if a custom image tag is set, e.g. 'image:menu' | 
					
						
							|  |  |  |                */ | 
					
						
							|  |  |  |             const prefixes = tagKey ?? imageProvider.defaultKeyPrefixes | 
					
						
							| 
									
										
										
										
											2024-11-14 18:25:27 +01:00
										 |  |  |             console.log("Prefixes are", tagKey, prefixes) | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |             const singleSource = tags.bindD((tags) => imageProvider.getRelevantUrls(tags, prefixes)) | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  |             allSources.push(singleSource) | 
					
						
							|  |  |  |             singleSource.addCallbackAndRunD((_) => { | 
					
						
							| 
									
										
										
										
											2021-11-07 16:34:51 +01:00
										 |  |  |                 const all: ProvidedImage[] = [].concat(...allSources.map((source) => source.data)) | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |                 const dedup = Utils.DedupOnId(all, (i) => i?.id ?? i?.url) | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  |                 source.set(dedup) | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  |             }) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-11-14 18:25:27 +01:00
										 |  |  |         this._cachedImageStores[cachekey] = source | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  |         return source | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-08 12:41:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Given a list of URLs, tries to detect the images. Used in e.g. the comments | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static loadImagesFrom(urls: string[]): Store<ProvidedImage[]> { | 
					
						
							|  |  |  |         const tags = { | 
					
						
							| 
									
										
										
										
											2024-11-24 23:54:13 +01:00
										 |  |  |             id: urls.join(";"), | 
					
						
							| 
									
										
										
										
											2024-10-08 12:41:14 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         for (let i = 0; i < urls.length; i++) { | 
					
						
							| 
									
										
										
										
											2024-11-24 23:54:13 +01:00
										 |  |  |             tags["image:" + i] = urls[i] | 
					
						
							| 
									
										
										
										
											2024-10-08 12:41:14 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         return this.LoadImagesFor(new ImmutableStore(tags)) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-22 14:21:32 +02:00
										 |  |  | } |