Skip to content

Instantly share code, notes, and snippets.

@sebilasse
Created March 7, 2025 11:23
Show Gist options
  • Save sebilasse/b5370e2123145539598137c53ffb49a3 to your computer and use it in GitHub Desktop.
Save sebilasse/b5370e2123145539598137c53ffb49a3 to your computer and use it in GitHub Desktop.
wd utils (v1.1) to `as`, as described to max in fedi
import { AsObjectNormalized } from "@AS";
import { HEADERS } from "@/lib/constants.ts";
import { createHash } from "https://deno.land/[email protected]/hash/mod.ts";
export interface WikiPropertyVar {
name: string;
property: string;
container: string | string[];
type: string | string[];
functional: boolean;
}
export const defaultWdOptions = {
keepTypes: true, keepQualifiers: true, keepRichValues: true
};
export const wikiIdRegex = /^Q\d+$/;
export const WDPROP = 'https://www.wikidata.org/prop/direct/';
export const wdFilter = (o: any) => !!o.wdt;
export const wdReduce = (r: any, o: any) => { r[o.property] = o; return r; }
export const wdMap = (o: any) => (o.property.indexOf('wdt:') === 0)
? {...o, wdt: true, property: o.property.replace('wdt:', '')}
: (o.property.indexOf(WDPROP) === 0
? {...o, wdt: true, property: o.property.replace(WDPROP, '')}
: { ...o, wdt: false }
);
export const getId = (wd: string|{id?: string; amount?: number}, idMap, wdId = '') => {
if (typeof wd === 'object' && wd?.amount) return wd.amount;
const id: any = typeof wd === 'object' ? wd.id : wd;
return id && idMap[id]
? `redaktor:${idMap[id]}`
: (wikiIdRegex.test(id||wdId) ? `wd:${id||wdId}` : (id||wdId||''));
}
export const withHreflang = (link, qualifiers, idMap) => {
if (qualifiers?.P407) {
link['wdt:P407'] = `wd:${qualifiers.P407[0]?.value}`;
if (idMap[qualifiers.P407[0]?.value]) {
link.hreflang = idMap[qualifiers.P407[0].value];
}
if (qualifiers.P407[0]?.value === 'Q20923490') {
link.summaryMap = {
en: 'multiple languages', de: 'mehrsprachig', fr: 'multilingue',
es: 'multilingüe', pt: 'multilingue', und: 'multilanguage',
}
}
}
return link
}
export const qualifyFactory = (qualifiers, idMap, labelcache) => (r: AsObjectNormalized, qk) => {
r[`wdt:${qk}`] = [getId(qualifiers[qk][0].value, idMap)]
const { value } = qualifiers[qk][0];
if (typeof value === 'string' && labelcache[value]) {
if (!r.nameMap) {
r.nameMap = labelcache[value];
} else {
for (const l in labelcache[value]) {
r.nameMap[l] = !!r.nameMap[l]
? `${r.nameMap[l]} / ${labelcache[value][l]}`
: labelcache[value][l];
}
}
}
return r;
}
function getWikiImgSrc(filename: string) {
const wmBase = 'https://upload.wikimedia.org/wikipedia/commons/';
const wms = filename.replace(/\s/g, '_');
const md5s = createHash('md5').update(wms).toString();
const [a, b] = [md5s.charAt(0), md5s.charAt(1)];
return `${wmBase}${a}/${a}${b}/${encodeURIComponent(wms)}`;
}
export function createWikiMedia(src: string, context?: string) {
if (!src || typeof src !== 'string') {
return {};
}
src = getWikiImgSrc(src);
const url: any = [
{
type: ['Link'],
href: src
},
];
if (context) {
url[0].context = Array.isArray(context) ? context : [context];
}
const imgSizeM = src.match(/(\d{2,3})x(\d{2,3})[.]([a-z]*)([?]|$)/i) || [];
const imgTypeM = src.match(/[.]([a-z]*)([?]|$)/i) || [];
const imgSize = imgSizeM.length > 2 && [imgSizeM[1], imgSizeM[2]];
const imgType = imgTypeM.length > 1 && imgTypeM[1].toLowerCase();
if (imgType === 'svg') {
url[0].mediaType = 'image/svg+xml';
} else if (imgType === 'png' || imgType === 'jpg') {
url[0].mediaType = `image/${imgType}`;
}
if (imgSize) {
url[0].width = imgSize[0];
url[0].height = imgSize[1];
}
return {
type: 'Image',
url
};
}
export function getPropertiesFromContext(
contexts: any,
result: WikiPropertyVar[] = [],
) {
if (!Array.isArray(contexts)) contexts = [contexts];
return contexts.reduce((res: any, c: any) => {
if (Array.isArray(c)) {
res = getPropertiesFromContext(c, res);
} else if (typeof c === 'object') {
const o = c['@context'] ? c['@context'] : c;
for (const name in o) {
console.log(name, o[name]['@id'])
//shortName: { '@id': 'wdt:P1813', '@type': ['owl:FunctionalProperty'] },
const property = o[name]['@id'];
if (property) {
const type = o[name]['@type'];
const container = o[name]['@container'];
const fA = (Array.isArray(type) ? type : [type])
.filter((s) =>
typeof s === 'string' && s.indexOf('FunctionalProperty') > -1
);
res.push({
name,
property,
type,
container,
functional: !!fA.length,
prefix: o[name].prefix || '',
suffix: o[name].suffix || '',
});
}
}
}
return res;
}, result);
}
export const getWD = (url: string, i: number) => new Promise((resolve) => {
setTimeout(() => {
try {
fetch(url, HEADERS.GET.JSON).then((r) => {
if (!r.ok) resolve([]);
return r.json();
}).then((res: any) => {
if (!res) return resolve([]);
const { entities } = res;
try {
resolve(entities);
} catch (e) {
console.log(e);
resolve([]);
}
}).catch((e) => {
console.log(e);
resolve([]);
});
} catch (e) {
resolve([]);
}
}, (400 * i) + (Math.random() * 800));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment