forked from MapComplete/MapComplete
Graciously handle multiple entries in wikidata for fetching images and showing articles, verious bug fixes
This commit is contained in:
parent
8d52ef1106
commit
a996ba2a7c
14 changed files with 231 additions and 90 deletions
|
@ -1,17 +1,20 @@
|
|||
import {UIEventSource} from "../UIEventSource";
|
||||
import BaseUIElement from "../../UI/BaseUIElement";
|
||||
import {LicenseInfo} from "./LicenseInfo";
|
||||
import {Utils} from "../../Utils";
|
||||
|
||||
export interface ProvidedImage {
|
||||
url: string, key: string, provider: ImageProvider
|
||||
url: string,
|
||||
key: string,
|
||||
provider: ImageProvider
|
||||
}
|
||||
|
||||
export default abstract class ImageProvider {
|
||||
|
||||
public abstract readonly defaultKeyPrefixes : string[] = ["mapillary", "image"]
|
||||
|
||||
|
||||
public abstract readonly defaultKeyPrefixes: string[] = ["mapillary", "image"]
|
||||
|
||||
private _cache = new Map<string, UIEventSource<LicenseInfo>>()
|
||||
|
||||
|
||||
GetAttributionFor(url: string): UIEventSource<LicenseInfo> {
|
||||
const cached = this._cache.get(url);
|
||||
if (cached !== undefined) {
|
||||
|
@ -31,43 +34,49 @@ export default abstract class ImageProvider {
|
|||
*/
|
||||
public GetRelevantUrls(allTags: UIEventSource<any>, options?: {
|
||||
prefixes?: string[]
|
||||
}):UIEventSource<ProvidedImage[]> {
|
||||
}): UIEventSource<ProvidedImage[]> {
|
||||
const prefixes = options?.prefixes ?? this.defaultKeyPrefixes
|
||||
if(prefixes === undefined){
|
||||
throw "The image provider"+this.constructor.name+" doesn't define `defaultKeyPrefixes`"
|
||||
if (prefixes === undefined) {
|
||||
throw "The image provider" + this.constructor.name + " doesn't define `defaultKeyPrefixes`"
|
||||
}
|
||||
const relevantUrls = new UIEventSource<{ url: string; key: string; provider: ImageProvider }[]>([])
|
||||
const seenValues = new Set<string>()
|
||||
const self = this
|
||||
const self =this
|
||||
allTags.addCallbackAndRunD(tags => {
|
||||
for (const key in tags) {
|
||||
if(!prefixes.some(prefix => key.startsWith(prefix))){
|
||||
if (!prefixes.some(prefix => key.startsWith(prefix))) {
|
||||
continue
|
||||
}
|
||||
const value = tags[key]
|
||||
if(seenValues.has(value)){
|
||||
continue
|
||||
}
|
||||
seenValues.add(value)
|
||||
this.ExtractUrls(key, value).then(promises => {
|
||||
for (const promise of promises ?? []) {
|
||||
if(promise === undefined){
|
||||
continue
|
||||
}
|
||||
promise.then(providedImage => {
|
||||
if(providedImage === undefined){
|
||||
return
|
||||
}
|
||||
relevantUrls.data.push(providedImage)
|
||||
relevantUrls.ping()
|
||||
})
|
||||
const values = Utils.NoEmpty(tags[key]?.split(";")?.map(v => v.trim()) ?? [])
|
||||
for (const value of values) {
|
||||
|
||||
if (seenValues.has(value)) {
|
||||
continue
|
||||
}
|
||||
})
|
||||
seenValues.add(value)
|
||||
this.ExtractUrls(key, value).then(promises => {
|
||||
console.log("Got ", promises.length, "promises for", value,"by",self.constructor.name)
|
||||
for (const promise of promises ?? []) {
|
||||
if (promise === undefined) {
|
||||
continue
|
||||
}
|
||||
promise.then(providedImage => {
|
||||
if (providedImage === undefined) {
|
||||
return
|
||||
}
|
||||
relevantUrls.data.push(providedImage)
|
||||
relevantUrls.ping()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
return relevantUrls
|
||||
}
|
||||
|
||||
public abstract ExtractUrls(key: string, value: string) : Promise<Promise<ProvidedImage>[]>;
|
||||
|
||||
public abstract ExtractUrls(key: string, value: string): Promise<Promise<ProvidedImage>[]>;
|
||||
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
export class LicenseInfo {
|
||||
title: string = ""
|
||||
artist: string = "";
|
||||
license: string = "";
|
||||
licenseShortName: string = "";
|
||||
|
|
|
@ -65,12 +65,26 @@ export class WikimediaImageProvider extends ImageProvider {
|
|||
"&format=json&origin=*";
|
||||
const data = await Utils.downloadJson(url)
|
||||
const licenseInfo = new LicenseInfo();
|
||||
const license = (data.query.pages[-1].imageinfo ?? [])[0]?.extmetadata;
|
||||
const pageInfo = data.query.pages[-1]
|
||||
if(pageInfo === undefined){
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const license = (pageInfo.imageinfo ?? [])[0]?.extmetadata;
|
||||
if (license === undefined) {
|
||||
console.warn("The file", filename ,"has no usable metedata or license attached... Please fix the license info file yourself!")
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let title = pageInfo.title
|
||||
if(title.startsWith("File:")){
|
||||
title= title.substr("File:".length)
|
||||
}
|
||||
if(title.endsWith(".jpg") || title.endsWith(".png")){
|
||||
title = title.substring(0, title.length - 4)
|
||||
}
|
||||
|
||||
licenseInfo.title = title
|
||||
licenseInfo.artist = license.Artist?.value;
|
||||
licenseInfo.license = license.License?.value;
|
||||
licenseInfo.copyrighted = license.Copyrighted?.value;
|
||||
|
|
|
@ -47,7 +47,7 @@ export default class Wikidata {
|
|||
const claimsList: any[] = entity.claims[claimId]
|
||||
const values = new Set<string>()
|
||||
for (const claim of claimsList) {
|
||||
const value = claim.mainsnak?.datavalueq?.value;
|
||||
const value = claim.mainsnak?.datavalue?.value;
|
||||
if(value !== undefined){
|
||||
values.add(value)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,10 @@ export default class Wikipedia {
|
|||
"mw-selflink",
|
||||
"hatnote" // Often redirects
|
||||
]
|
||||
|
||||
private static readonly idsToRemove = [
|
||||
"sjabloon_zie"
|
||||
]
|
||||
|
||||
private static readonly _cache = new Map<string, UIEventSource<{ success: string } | { error: any }>>()
|
||||
|
||||
|
@ -59,6 +63,13 @@ export default class Wikipedia {
|
|||
}
|
||||
}
|
||||
|
||||
for (const forbiddenId of Wikipedia.idsToRemove) {
|
||||
const toRemove = content.querySelector("#"+forbiddenId)
|
||||
toRemove?.parentElement?.removeChild(toRemove)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const links = Array.from(content.getElementsByTagName("a"))
|
||||
|
||||
// Rewrite relative links to absolute links + open them in a new tab
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue