Fix visualisation of licenses

This commit is contained in:
pietervdvn 2022-06-13 00:51:53 +02:00
parent e3b9bf2434
commit 771c59ab92
11 changed files with 37 additions and 36 deletions

View file

@ -13,18 +13,6 @@ export default abstract class ImageProvider {
public abstract readonly defaultKeyPrefixes: string[] public abstract readonly defaultKeyPrefixes: string[]
private _cache = new Map<string, UIEventSource<LicenseInfo>>()
GetAttributionFor(url: string): UIEventSource<LicenseInfo> {
const cached = this._cache.get(url);
if (cached !== undefined) {
return cached;
}
const src = UIEventSource.FromPromise(this.DownloadAttribution(url))
this._cache.set(url, src)
return src;
}
public abstract SourceIcon(backlinkSource?: string): BaseUIElement; public abstract SourceIcon(backlinkSource?: string): BaseUIElement;
/** /**
@ -75,6 +63,6 @@ export default abstract class ImageProvider {
public abstract ExtractUrls(key: string, value: string): Promise<Promise<ProvidedImage>[]>; public abstract ExtractUrls(key: string, value: string): Promise<Promise<ProvidedImage>[]>;
protected abstract DownloadAttribution(url: string): Promise<LicenseInfo>; public abstract DownloadAttribution(url: string): Promise<LicenseInfo>;
} }

View file

@ -99,11 +99,23 @@ export class Imgur extends ImageProvider {
return [] return []
} }
protected DownloadAttribution: (url: string) => Promise<LicenseInfo> = async (url: string) => { /**
* Download the attribution from attribution
*
* 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)
* const licenseInfo = await Imgur.singleton.DownloadAttribution("https://i.imgur.com/E0RuAK3.jpg")
* const expected = new LicenseInfo()
* expected.licenseShortName = "CC-BY 4.0"
* expected.artist = "Pieter Vander Vennet"
* licenseInfo // => expected
*/
public async DownloadAttribution (url: string) : Promise<LicenseInfo> {
const hash = url.substr("https://i.imgur.com/".length).split(".jpg")[0]; const hash = url.substr("https://i.imgur.com/".length).split(".jpg")[0];
const apiUrl = 'https://api.imgur.com/3/image/' + hash; const apiUrl = 'https://api.imgur.com/3/image/' + hash;
const response = await Utils.downloadJson(apiUrl, {Authorization: 'Client-ID ' + Constants.ImgurApiKey}) const response = await Utils.downloadJsonCached(apiUrl, 365*24*60*60,
{Authorization: 'Client-ID ' + Constants.ImgurApiKey})
const descr: string = response.data.description ?? ""; const descr: string = response.data.description ?? "";
const data: any = {}; const data: any = {};

View file

@ -1,7 +1,7 @@
export class LicenseInfo { export class LicenseInfo {
title: string = "" title: string = ""
artist: string = ""; artist: string = "";
license: string = ""; license: string = undefined;
licenseShortName: string = ""; licenseShortName: string = "";
usageTerms: string = ""; usageTerms: string = "";
attributionRequired: boolean = false; attributionRequired: boolean = false;

View file

@ -4,7 +4,6 @@ import Svg from "../../Svg";
import {Utils} from "../../Utils"; import {Utils} from "../../Utils";
import {LicenseInfo} from "./LicenseInfo"; import {LicenseInfo} from "./LicenseInfo";
import Constants from "../../Models/Constants"; import Constants from "../../Models/Constants";
import * as Console from "console";
export class Mapillary extends ImageProvider { export class Mapillary extends ImageProvider {
@ -82,7 +81,7 @@ export class Mapillary extends ImageProvider {
return [this.PrepareUrlAsync(key, value)] return [this.PrepareUrlAsync(key, value)]
} }
protected async DownloadAttribution(url: string): Promise<LicenseInfo> { public async DownloadAttribution(url: string): Promise<LicenseInfo> {
const license = new LicenseInfo() const license = new LicenseInfo()
license.artist = "Contributor name unavailable"; license.artist = "Contributor name unavailable";
license.license = "CC BY-SA 4.0"; license.license = "CC BY-SA 4.0";
@ -98,7 +97,7 @@ export class Mapillary extends ImageProvider {
} }
const metadataUrl = 'https://graph.mapillary.com/' + mapillaryId + '?fields=thumb_1024_url&&access_token=' + Constants.mapillary_client_token_v4; const metadataUrl = 'https://graph.mapillary.com/' + mapillaryId + '?fields=thumb_1024_url&&access_token=' + Constants.mapillary_client_token_v4;
const response = await Utils.downloadJson(metadataUrl) const response = await Utils.downloadJsonCached(metadataUrl,60*60)
const url = <string>response["thumb_1024_url"]; const url = <string>response["thumb_1024_url"];
return { return {
url: url, url: url,

View file

@ -46,7 +46,7 @@ export class WikidataImageProvider extends ImageProvider {
return allImages return allImages
} }
protected DownloadAttribution(url: string): Promise<any> { public DownloadAttribution(url: string): Promise<any> {
throw new Error("Method not implemented; shouldn't be needed!"); throw new Error("Method not implemented; shouldn't be needed!");
} }

View file

@ -112,7 +112,7 @@ export class WikimediaImageProvider extends ImageProvider {
return [Promise.resolve(this.UrlForImage("File:" + value))] return [Promise.resolve(this.UrlForImage("File:" + value))]
} }
protected async DownloadAttribution(filename: string): Promise<LicenseInfo> { public async DownloadAttribution(filename: string): Promise<LicenseInfo> {
filename = WikimediaImageProvider.ExtractFileName(filename) filename = WikimediaImageProvider.ExtractFileName(filename)
if (filename === "") { if (filename === "") {
@ -123,7 +123,7 @@ export class WikimediaImageProvider extends ImageProvider {
"api.php?action=query&prop=imageinfo&iiprop=extmetadata&" + "api.php?action=query&prop=imageinfo&iiprop=extmetadata&" +
"titles=" + filename + "titles=" + filename +
"&format=json&origin=*"; "&format=json&origin=*";
const data = await Utils.downloadJson(url) const data = await Utils.downloadJsonCached(url,365*24*60*60)
const licenseInfo = new LicenseInfo(); const licenseInfo = new LicenseInfo();
const pageInfo = data.query.pages[-1] const pageInfo = data.query.pages[-1]
if (pageInfo === undefined) { if (pageInfo === undefined) {

View file

@ -23,7 +23,7 @@
* *
* [ * [
* { * {
* // The first pair: key --> X, a|b|c --> 0 * # The first pair: key --> X, a|b|c --> 0
* "X": 0 * "X": 0
* }, * },
* { * {

View file

@ -1,9 +1,10 @@
import Combine from "../Base/Combine"; import Combine from "../Base/Combine";
import Attribution from "./Attribution"; import Attribution from "./Attribution";
import Img from "../Base/Img"; import Img from "../Base/Img";
import ImageProvider, {ProvidedImage} from "../../Logic/ImageProviders/ImageProvider"; import ImageProvider from "../../Logic/ImageProviders/ImageProvider";
import BaseUIElement from "../BaseUIElement"; import BaseUIElement from "../BaseUIElement";
import {Mapillary} from "../../Logic/ImageProviders/Mapillary"; import {Mapillary} from "../../Logic/ImageProviders/Mapillary";
import {UIEventSource} from "../../Logic/UIEventSource";
export class AttributedImage extends Combine { export class AttributedImage extends Combine {
@ -21,7 +22,7 @@ export class AttributedImage extends Combine {
let attr: BaseUIElement = undefined let attr: BaseUIElement = undefined
if(imageInfo.provider !== undefined){ if(imageInfo.provider !== undefined){
attr = new Attribution(imageInfo.provider?.GetAttributionFor(imageInfo.url), attr = new Attribution(UIEventSource.FromPromise( imageInfo.provider?.DownloadAttribution(imageInfo.url)),
imageInfo.provider?.SourceIcon(), imageInfo.provider?.SourceIcon(),
imageInfo.date imageInfo.date
) )

View file

@ -24,7 +24,7 @@ export default class Attribution extends VariableUiElement {
new Combine([ new Combine([
Translations.W(license?.title).SetClass("block"), Translations.W(license?.title).SetClass("block"),
Translations.W(license?.artist ?? "").SetClass("block font-bold"), Translations.W(license?.artist ?? "").SetClass("block font-bold"),
Translations.W((license?.license ?? "") === "" ? "CC0" : (license?.license ?? "")), Translations.W(license?.license ?? license?.licenseShortName),
date === undefined ? undefined : new FixedUiElement(date.toLocaleDateString()) date === undefined ? undefined : new FixedUiElement(date.toLocaleDateString())
]).SetClass("flex flex-col") ]).SetClass("flex flex-col")
]).SetClass("flex flex-row bg-black text-white text-sm absolute bottom-0 left-0 p-0.5 pl-5 pr-3 rounded-lg no-images") ]).SetClass("flex flex-row bg-black text-white text-sm absolute bottom-0 left-0 p-0.5 pl-5 pr-3 rounded-lg no-images")

19
package-lock.json generated
View file

@ -26,9 +26,8 @@
"@types/prompt-sync": "^4.1.0", "@types/prompt-sync": "^4.1.0",
"@types/wikidata-sdk": "^6.1.0", "@types/wikidata-sdk": "^6.1.0",
"@types/xml2js": "^0.4.9", "@types/xml2js": "^0.4.9",
"core-js": "^3.22.8",
"country-language": "^0.1.7", "country-language": "^0.1.7",
"doctest-ts-improved": "^0.8.6", "doctest-ts-improved": "^0.8.8",
"email-validator": "^2.0.4", "email-validator": "^2.0.4",
"escape-html": "^1.0.3", "escape-html": "^1.0.3",
"geojson2svg": "^1.3.1", "geojson2svg": "^1.3.1",
@ -4899,6 +4898,7 @@
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.8.tgz", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.8.tgz",
"integrity": "sha512-UoGQ/cfzGYIuiq6Z7vWL1HfkE9U9IZ4Ub+0XSiJTCzvbZzgPA69oDF2f+lgJ6dFFLEdjW5O6svvoKzXX23xFkA==", "integrity": "sha512-UoGQ/cfzGYIuiq6Z7vWL1HfkE9U9IZ4Ub+0XSiJTCzvbZzgPA69oDF2f+lgJ6dFFLEdjW5O6svvoKzXX23xFkA==",
"hasInstallScript": true, "hasInstallScript": true,
"optional": true,
"funding": { "funding": {
"type": "opencollective", "type": "opencollective",
"url": "https://opencollective.com/core-js" "url": "https://opencollective.com/core-js"
@ -6057,9 +6057,9 @@
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
}, },
"node_modules/doctest-ts-improved": { "node_modules/doctest-ts-improved": {
"version": "0.8.6", "version": "0.8.8",
"resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.6.tgz", "resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.8.tgz",
"integrity": "sha512-J7fXMJ29ve6DUsUHKEO5bOwGmYjhNZd88L7NMVDKIiLIiUCJ9zkR2k7IZOGjMC0RXw/q788REawcMUgIj+7Muw==", "integrity": "sha512-aEkS6go+DBz8atfQSAUoCXc0N+nI2YKFXOhS9j/Jrxv0rG0J+6e6xDxiZq0rP6sKybRF/zHSWqC2jjR9qzx2ZA==",
"dependencies": { "dependencies": {
"@types/chai": "^4.3.0", "@types/chai": "^4.3.0",
"chai": "^4.3.6", "chai": "^4.3.6",
@ -20572,7 +20572,8 @@
"core-js": { "core-js": {
"version": "3.22.8", "version": "3.22.8",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.8.tgz", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.8.tgz",
"integrity": "sha512-UoGQ/cfzGYIuiq6Z7vWL1HfkE9U9IZ4Ub+0XSiJTCzvbZzgPA69oDF2f+lgJ6dFFLEdjW5O6svvoKzXX23xFkA==" "integrity": "sha512-UoGQ/cfzGYIuiq6Z7vWL1HfkE9U9IZ4Ub+0XSiJTCzvbZzgPA69oDF2f+lgJ6dFFLEdjW5O6svvoKzXX23xFkA==",
"optional": true
}, },
"core-js-compat": { "core-js-compat": {
"version": "3.12.0", "version": "3.12.0",
@ -21466,9 +21467,9 @@
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
}, },
"doctest-ts-improved": { "doctest-ts-improved": {
"version": "0.8.6", "version": "0.8.8",
"resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.6.tgz", "resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.8.tgz",
"integrity": "sha512-J7fXMJ29ve6DUsUHKEO5bOwGmYjhNZd88L7NMVDKIiLIiUCJ9zkR2k7IZOGjMC0RXw/q788REawcMUgIj+7Muw==", "integrity": "sha512-aEkS6go+DBz8atfQSAUoCXc0N+nI2YKFXOhS9j/Jrxv0rG0J+6e6xDxiZq0rP6sKybRF/zHSWqC2jjR9qzx2ZA==",
"requires": { "requires": {
"@types/chai": "^4.3.0", "@types/chai": "^4.3.0",
"chai": "^4.3.6", "chai": "^4.3.6",

View file

@ -83,7 +83,7 @@
"@types/wikidata-sdk": "^6.1.0", "@types/wikidata-sdk": "^6.1.0",
"@types/xml2js": "^0.4.9", "@types/xml2js": "^0.4.9",
"country-language": "^0.1.7", "country-language": "^0.1.7",
"doctest-ts-improved": "^0.8.6", "doctest-ts-improved": "^0.8.8",
"email-validator": "^2.0.4", "email-validator": "^2.0.4",
"escape-html": "^1.0.3", "escape-html": "^1.0.3",
"geojson2svg": "^1.3.1", "geojson2svg": "^1.3.1",