Further stabilization of wikipedia box

This commit is contained in:
Pieter Vander Vennet 2021-10-03 01:38:57 +02:00
parent 393d5d8932
commit a89d303ecd
15 changed files with 169 additions and 109 deletions

View file

@ -23,7 +23,10 @@ export class WikidataImageProvider extends ImageProvider {
}
public async ExtractUrls(key: string, value: string): Promise<Promise<ProvidedImage>[]> {
const entity = await Wikidata.LoadWikidataEntry(value)
const entity = await Wikidata.LoadWikidataEntryAsync(value)
if(entity === undefined){
return []
}
const allImages : Promise<ProvidedImage>[] = []
// P18 is the claim 'depicted in this image'
@ -32,7 +35,7 @@ export class WikidataImageProvider extends ImageProvider {
allImages.push(...promises)
}
const commons =entity.wikisites.get("commons")
const commons = entity.commons
if (commons !== undefined) {
const promises = await WikimediaImageProvider.singleton.ExtractUrls(undefined , commons)
allImages.push(...promises)

View file

@ -18,7 +18,8 @@ export class Overpass {
private _relationTracker: RelationsTracker;
constructor(filter: TagsFilter, extraScripts: string[],
constructor(filter: TagsFilter,
extraScripts: string[],
interpreterUrl: string,
timeout: UIEventSource<number>,
relationTracker: RelationsTracker,

View file

@ -1,4 +1,5 @@
import {Utils} from "../Utils";
import * as Events from "events";
export class UIEventSource<T> {
@ -32,14 +33,14 @@ export class UIEventSource<T> {
return [];
}
public static flatten<X>(source: UIEventSource<UIEventSource<X>>, possibleSources: UIEventSource<any>[]): UIEventSource<X> {
public static flatten<X>(source: UIEventSource<UIEventSource<X>>, possibleSources?: UIEventSource<any>[]): UIEventSource<X> {
const sink = new UIEventSource<X>(source.data?.data);
source.addCallback((latestData) => {
sink.setData(latestData?.data);
});
for (const possibleSource of possibleSources) {
for (const possibleSource of possibleSources ?? []) {
possibleSource?.addCallback(() => {
sink.setData(source.data?.data);
})
@ -186,6 +187,25 @@ export class UIEventSource<T> {
}
}
/**
* Monadic bind function
*/
public bind<X>(f: ((t: T) => UIEventSource<X>)): UIEventSource<X>{
const sink = new UIEventSource<X>( undefined )
const seenEventSources = new Set<UIEventSource<X>>();
this.addCallbackAndRun(data => {
const eventSource = f(data)
if(eventSource === undefined){
sink.setData(undefined)
}else if(!seenEventSources.has(eventSource)){
eventSource.addCallbackAndRun(mappedData => sink.setData(mappedData))
seenEventSources.add(eventSource)
}
})
return sink;
}
/**
* Monoidal map:
* Given a function 'f', will construct a new UIEventSource where the contents will always be "f(this.data)'

View file

@ -1,4 +1,5 @@
import {Utils} from "../../Utils";
import {UIEventSource} from "../UIEventSource";
export interface WikidataResponse {
@ -62,15 +63,23 @@ export default class Wikidata {
}
}
/**
* Loads a wikidata page
* @returns the entity of the given value
*/
public static async LoadWikidataEntry(value: string | number): Promise<WikidataResponse> {
const wikidataUrl = "https://www.wikidata.org/wiki/"
if (typeof value === "number") {
value = "Q" + value
private static readonly _cache = new Map<number, UIEventSource<{success: WikidataResponse} | {error: any}>>()
public static LoadWikidataEntry(value: string | number): UIEventSource<{success: WikidataResponse} | {error: any}> {
const key = this.ExtractKey(value)
const cached = Wikidata._cache.get(key)
if(cached !== undefined){
return cached
}
const src = UIEventSource.FromPromiseWithErr(Wikidata.LoadWikidataEntryAsync(key))
Wikidata._cache.set(key, src)
return src;
}
private static ExtractKey(value: string | number) : number{
if (typeof value === "number") {
return value
}
const wikidataUrl = "https://www.wikidata.org/wiki/"
if (value.startsWith(wikidataUrl)) {
value = value.substring(wikidataUrl.length)
}
@ -78,12 +87,30 @@ export default class Wikidata {
// Probably some random link in the image field - we skip it
return undefined
}
if (!value.startsWith("Q")) {
value = "Q" + value
if (value.startsWith("Q")) {
value = value.substring(1)
}
const url = "https://www.wikidata.org/wiki/Special:EntityData/" + value + ".json";
const n = Number(value)
if(isNaN(n)){
return undefined
}
return n;
}
/**
* Loads a wikidata page
* @returns the entity of the given value
*/
public static async LoadWikidataEntryAsync(value: string | number): Promise<WikidataResponse> {
const id = Wikidata.ExtractKey(value)
if(id === undefined){
console.warn("Could not extract a wikidata entry from", value)
return undefined;
}
console.log("Requesting wikidata with id", id)
const url = "https://www.wikidata.org/wiki/Special:EntityData/Q" + id + ".json";
const response = await Utils.downloadJson(url)
return Wikidata.ParseResponse(response.entities[value]);
return Wikidata.ParseResponse(response.entities["Q" + id])
}
}

View file

@ -61,7 +61,6 @@ export default class Wikipedia {
const links = Array.from(content.getElementsByTagName("a"))
console.log("Links are", links)
// Rewrite relative links to absolute links + open them in a new tab
links.filter(link => link.getAttribute("href")?.startsWith("/") ?? false).
forEach(link => {