Refactoring: image providers use ID everywhere

This commit is contained in:
Pieter Vander Vennet 2025-06-05 12:21:38 +02:00
parent d9c1fe3f74
commit 1ddfffcee0
6 changed files with 19 additions and 20 deletions

View file

@ -124,8 +124,7 @@ export default abstract class ImageProvider {
): undefined | ProvidedImage[] | Promise<ProvidedImage[]> ): undefined | ProvidedImage[] | Promise<ProvidedImage[]>
public abstract DownloadAttribution(providedImage: { public abstract DownloadAttribution(providedImage: {
url: string id: string
id?: string
}): Promise<LicenseInfo> }): Promise<LicenseInfo>
public abstract apiUrls(): string[] public abstract apiUrls(): string[]
@ -142,7 +141,7 @@ export default abstract class ImageProvider {
id: string id: string
}): Promise<Feature<Point, PanoramaView>> | undefined }): Promise<Feature<Point, PanoramaView>> | undefined
public static async offerImageAsDownload(image: ProvidedImage) { public static async offerImageAsDownload(image: { url_hd?: string, url: string }) {
const response = await fetch(image.url_hd ?? image.url) const response = await fetch(image.url_hd ?? image.url)
const blob = await response.blob() const blob = await response.blob()
Utils.offerContentsAsDownloadableFile(blob, new URL(image.url).pathname.split("/").at(-1), { Utils.offerContentsAsDownloadableFile(blob, new URL(image.url).pathname.split("/").at(-1), {

View file

@ -75,27 +75,27 @@ export class Imgur extends ImageProvider {
* *
* const data = {"data":{"id":"I9t6B7B","title":"Station Knokke","description":"author:Pieter Vander Vennet\r\nlicense:CC-BY 4.0\r\nosmid:node\/9812712386","datetime":1655052078,"type":"image\/jpeg","animated":false,"width":2400,"height":1795,"size":910872,"views":2,"bandwidth":1821744,"vote":null,"favorite":false,"nsfw":false,"section":null,"account_url":null,"account_id":null,"is_ad":false,"in_most_viral":false,"has_sound":false,"tags":[],"ad_type":0,"ad_url":"","edited":"0","in_gallery":false,"link":"https:\/\/i.imgur.com\/I9t6B7B.jpg","ad_config":{"safeFlags":["not_in_gallery","share"],"highRiskFlags":[],"unsafeFlags":["sixth_mod_unsafe"],"wallUnsafeFlags":[],"showsAds":false,"showAdLevel":1}},"success":true,"status":200} * const data = {"data":{"id":"I9t6B7B","title":"Station Knokke","description":"author:Pieter Vander Vennet\r\nlicense:CC-BY 4.0\r\nosmid:node\/9812712386","datetime":1655052078,"type":"image\/jpeg","animated":false,"width":2400,"height":1795,"size":910872,"views":2,"bandwidth":1821744,"vote":null,"favorite":false,"nsfw":false,"section":null,"account_url":null,"account_id":null,"is_ad":false,"in_most_viral":false,"has_sound":false,"tags":[],"ad_type":0,"ad_url":"","edited":"0","in_gallery":false,"link":"https:\/\/i.imgur.com\/I9t6B7B.jpg","ad_config":{"safeFlags":["not_in_gallery","share"],"highRiskFlags":[],"unsafeFlags":["sixth_mod_unsafe"],"wallUnsafeFlags":[],"showsAds":false,"showAdLevel":1}},"success":true,"status":200}
* Utils.injectJsonDownloadForTests("https://api.imgur.com/3/image/E0RuAK3", data) * Utils.injectJsonDownloadForTests("https://api.imgur.com/3/image/E0RuAK3", data)
* const licenseInfo = await Imgur.singleton.DownloadAttribution({url: "https://i.imgur.com/E0RuAK3.jpg"}) * const licenseInfo = await Imgur.singleton.DownloadAttribution({id: "https://i.imgur.com/E0RuAK3.jpg"})
* const expected = new LicenseInfo() * const expected = new LicenseInfo()
* expected.licenseShortName = "CC-BY 4.0" * expected.licenseShortName = "CC-BY 4.0"
* expected.artist = "Pieter Vander Vennet" * expected.artist = "Pieter Vander Vennet"
* expected.date = new Date(1655052078000) * expected.date = new Date(1655052078000)
* expected.views = 2 * expected.views = 2
* licenseInfo // => expected * licenseInfo // => expected
* const licenseInfoJpeg = await Imgur.singleton.DownloadAttribution({url:"https://i.imgur.com/E0RuAK3.jpeg"}) * const licenseInfoJpeg = await Imgur.singleton.DownloadAttribution({id:"https://i.imgur.com/E0RuAK3.jpeg"})
* licenseInfoJpeg // => expected * licenseInfoJpeg // => expected
* const licenseInfoUpperCase = await Imgur.singleton.DownloadAttribution({url: "https://i.imgur.com/E0RuAK3.JPEG"}) * const licenseInfoUpperCase = await Imgur.singleton.DownloadAttribution({id: "https://i.imgur.com/E0RuAK3.JPEG"})
* licenseInfoUpperCase // => expected * licenseInfoUpperCase // => expected
* *
* *
*/ */
public async DownloadAttribution( public async DownloadAttribution(
providedImage: { providedImage: {
url: string id: string
}, },
withResponse?: (obj) => void withResponse?: (obj) => void
): Promise<LicenseInfo> { ): Promise<LicenseInfo> {
const url = providedImage.url const url = providedImage.id
const hash = url.substr("https://i.imgur.com/".length).split(/(\.jpe?g)|(\.png)/i)[0] const hash = url.substr("https://i.imgur.com/".length).split(/(\.jpe?g)|(\.png)/i)[0]
const apiUrl = "https://api.imgur.com/3/image/" + hash const apiUrl = "https://api.imgur.com/3/image/" + hash

View file

@ -208,8 +208,7 @@ export default class PanoramaxImageProvider extends ImageProvider {
} }
public async DownloadAttribution(providedImage: { public async DownloadAttribution(providedImage: {
id: string, id: string
url: string // Actually not used
}): Promise<LicenseInfo> { }): Promise<LicenseInfo> {
const meta = await this.getInfoFor(providedImage.id) const meta = await this.getInfoFor(providedImage.id)

View file

@ -155,9 +155,9 @@ export class WikimediaImageProvider extends ImageProvider {
return [this.UrlForImage("File:" + value)] return [this.UrlForImage("File:" + value)]
} }
public async DownloadAttribution(img: { url: string }): Promise<LicenseInfo> { public async DownloadAttribution(img: { id: string }): Promise<LicenseInfo> {
const filename = "File:" + WikimediaImageProvider.extractFileName(img.url) const filename = "File:" + WikimediaImageProvider.extractFileName(img.id)
console.log("Downloading attribution for", filename, img.url) console.log("Downloading attribution for", filename, img.id)
if (filename === "") { if (filename === "") {
return undefined return undefined
} }

View file

@ -27,7 +27,7 @@ class CachedFetcher implements ImageFetcher {
private readonly _zoomlevel: number private readonly _zoomlevel: number
private readonly cache: Map<number, Promise<(P4CPicture & { id: string })[]>> = new Map< private readonly cache: Map<number, Promise<(P4CPicture & { id: string })[]>> = new Map<
number, number,
Promise<P4CPicture[]> Promise<(P4CPicture & { id: string })[]>
>() >()
public readonly name: string public readonly name: string
@ -124,8 +124,8 @@ class ImagesInLoadedDataFetcher implements ImageFetcher {
this._searchRadius = searchRadius this._searchRadius = searchRadius
} }
async fetchImages(lat: number, lon: number): Promise<P4CPicture[]> { async fetchImages(lat: number, lon: number): Promise<(P4CPicture & { id: string })[]> {
const foundImages: P4CPicture[] = [] const foundImages: (P4CPicture & { id: string })[] = []
this.indexedFeatures.features.data.forEach((feature) => { this.indexedFeatures.features.data.forEach((feature) => {
const props = feature.properties const props = feature.properties
const images = [] const images = []
@ -149,6 +149,7 @@ class ImagesInLoadedDataFetcher implements ImageFetcher {
foundImages.push({ foundImages.push({
pictureUrl: image, pictureUrl: image,
thumbUrl: image, thumbUrl: image,
id: image,
coordinates: { lng: centerpoint[0], lat: centerpoint[1] }, coordinates: { lng: centerpoint[0], lat: centerpoint[1] },
provider: "OpenStreetMap", provider: "OpenStreetMap",
details: { details: {
@ -182,9 +183,10 @@ class ImagesFromPanoramaxFetcher implements ImageFetcher {
} }
} }
private static convert(imageData: ImageData): P4CPicture { private static convert(imageData: ImageData): P4CPicture & { id: string } {
const [lng, lat] = imageData.geometry.coordinates const [lng, lat] = imageData.geometry.coordinates
return { return {
id: imageData.id,
pictureUrl: imageData.assets.sd.href, pictureUrl: imageData.assets.sd.href,
coordinates: { lng, lat }, coordinates: { lng, lat },
@ -205,7 +207,7 @@ class ImagesFromPanoramaxFetcher implements ImageFetcher {
} }
} }
public async fetchImages(lat: number, lon: number): Promise<P4CPicture[]> { public async fetchImages(lat: number, lon: number): Promise<(P4CPicture & { id: string })[]> {
const radiusSettings = [ const radiusSettings = [
{ {
place_fov_tolerance: 180, place_fov_tolerance: 180,
@ -372,7 +374,7 @@ export class CombinedFetcher {
start_captured_at: maxage, start_captured_at: maxage,
panoramas: "no", panoramas: "no",
}), }),
new P4CImageFetcher("mapillary"), // new P4CImageFetcher("mapillary"),
new P4CImageFetcher("wikicommons"), new P4CImageFetcher("wikicommons"),
].map((f) => new CachedFetcher(f)) ].map((f) => new CachedFetcher(f))
} }

View file

@ -42,7 +42,6 @@
provider = panoramaInfo.properties.provider provider = panoramaInfo.properties.provider
} }
console.log(">>> Got:", panoramaInfo, "by", provider.name) console.log(">>> Got:", panoramaInfo, "by", provider.name)
UI:
//actuallyDisplayed.set(image.properties.imageMeta) //actuallyDisplayed.set(image.properties.imageMeta)
}) })
if (Array.isArray(nearbyFeatures)) { if (Array.isArray(nearbyFeatures)) {