Add attribution script and some attributions

This commit is contained in:
pietervdvn 2021-04-07 01:32:39 +02:00
parent 99b0f937b7
commit 0fea2c87cd
11 changed files with 223 additions and 8 deletions

File diff suppressed because one or more lines are too long

View file

@ -38,6 +38,7 @@ import Combine from "./UI/Base/Combine";
import SelectedFeatureHandler from "./Logic/Actors/SelectedFeatureHandler"; import SelectedFeatureHandler from "./Logic/Actors/SelectedFeatureHandler";
import LZString from "lz-string"; import LZString from "lz-string";
import {LayoutConfigJson} from "./Customizations/JSON/LayoutConfigJson"; import {LayoutConfigJson} from "./Customizations/JSON/LayoutConfigJson";
import AttributionPanel from "./UI/BigComponents/AttributionPanel";
export class InitUiElements { export class InitUiElements {
@ -287,11 +288,7 @@ export class InitUiElements {
const copyrightNotice = const copyrightNotice =
new ScrollableFullScreen( new ScrollableFullScreen(
() => Translations.t.general.attribution.attributionTitle.Clone(), () => Translations.t.general.attribution.attributionTitle.Clone(),
() => new Combine([ () => new AttributionPanel(State.state.layoutToUse),
Translations.t.general.attribution.attributionContent,
"<br/>",
new Attribution(undefined, undefined, State.state.layoutToUse, undefined)
]),
"copyright" "copyright"
) )

View file

@ -10,6 +10,9 @@ import Loc from "../../Models/Loc";
import LeafletMap from "../../Models/LeafletMap"; import LeafletMap from "../../Models/LeafletMap";
import * as L from "leaflet" import * as L from "leaflet"
/**
* The bottom right attribution panel in the leaflet map
*/
export default class Attribution extends UIElement { export default class Attribution extends UIElement {
private readonly _location: UIEventSource<Loc>; private readonly _location: UIEventSource<Loc>;

View file

@ -0,0 +1,26 @@
import {UIElement} from "../UIElement";
import Combine from "../Base/Combine";
import Translations from "../i18n/Translations";
import Attribution from "./Attribution";
import State from "../../State";
import {UIEventSource} from "../../Logic/UIEventSource";
import LayoutConfig from "../../Customizations/JSON/LayoutConfig";
import {FixedUiElement} from "../Base/FixedUiElement";
/**
* The attribution panel shown on mobile
*/
export default class AttributionPanel extends Combine {
constructor(layoutToUse: UIEventSource<LayoutConfig>) {
super([
Translations.t.general.attribution.attributionContent,
Translations.t.general.attribution.themeBy.Subs({author: layoutToUse.data.maintainer}),
"<br/>",
new Attribution(undefined, undefined, State.state.layoutToUse, undefined),
"<br/>",
"<h4>", Translations.t.general.attribution.iconAttribution.title, "</h4>"
]);
}
}

View file

@ -520,6 +520,14 @@
}, },
"attributionContent": { "attributionContent": {
"en": "<p>All data is provided by <a href='https://osm.org' target='_blank'>OpenStreetMap</a>, freely reusable under <a href='https://osm.org/copyright' target='_blank'>the Open DataBase License</a>.</p><p>Some images are provided by Wikimedia</p>" "en": "<p>All data is provided by <a href='https://osm.org' target='_blank'>OpenStreetMap</a>, freely reusable under <a href='https://osm.org/copyright' target='_blank'>the Open DataBase License</a>.</p><p>Some images are provided by Wikimedia</p>"
},
"themeBy": {
"en": "Theme created by {author}"
},
"iconAttribution": {
"title": {
"en": "Used icons"
}
} }
}, },

28
package-lock.json generated
View file

@ -4029,6 +4029,11 @@
"integrity": "sha512-29GS75BE8asnTno3yB6ubOJOO0FboExEqNJy4bpz0GSmW/8wPTNL4h9h63c6s1uTrOopCmJYe/4yJLh5r92ZUA==", "integrity": "sha512-29GS75BE8asnTno3yB6ubOJOO0FboExEqNJy4bpz0GSmW/8wPTNL4h9h63c6s1uTrOopCmJYe/4yJLh5r92ZUA==",
"dev": true "dev": true
}, },
"@types/prompt-sync": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@types/prompt-sync/-/prompt-sync-4.1.0.tgz",
"integrity": "sha1-utMynv9bQRXjTvRpgjckTUEdRHA="
},
"@types/q": { "@types/q": {
"version": "1.5.4", "version": "1.5.4",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
@ -9903,6 +9908,29 @@
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
}, },
"prompt-sync": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/prompt-sync/-/prompt-sync-4.2.0.tgz",
"integrity": "sha512-BuEzzc5zptP5LsgV5MZETjDaKSWfchl5U9Luiu8SKp7iZWD5tZalOxvNcZRwv+d2phNFr8xlbxmFNcRKfJOzJw==",
"requires": {
"strip-ansi": "^5.0.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
},
"protocol-buffers-schema": { "protocol-buffers-schema": {
"version": "3.5.1", "version": "3.5.1",
"resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.5.1.tgz", "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.5.1.tgz",

View file

@ -13,11 +13,12 @@
"generate:editor-layer-index": "cd assets/ && wget https://osmlab.github.io/editor-layer-index/imagery.geojson --output-document=editor-layer-index.json", "generate:editor-layer-index": "cd assets/ && wget https://osmlab.github.io/editor-layer-index/imagery.geojson --output-document=editor-layer-index.json",
"generate:images": "ts-node scripts/generateIncludedImages.ts", "generate:images": "ts-node scripts/generateIncludedImages.ts",
"generate:translations": "ts-node scripts/generateTranslations.ts", "generate:translations": "ts-node scripts/generateTranslations.ts",
"generate:layouts": "ts-node scripts/createLayouts.ts", "generate:layouts": "ts-node scripts/generateLayouts.ts",
"generate:docs": "ts-node scripts/generateDocs.ts",
"optimize-images": "cd assets/generated/ && find -name '*.png' -exec optipng '{}' \\; && echo 'PNGs are optimized'", "optimize-images": "cd assets/generated/ && find -name '*.png' -exec optipng '{}' \\; && echo 'PNGs are optimized'",
"generate": "npm run generate:images && npm run generate:translations", "generate": "npm run generate:images && npm run generate:translations",
"build": "rm -rf dist/ && npm run generate && parcel build --public-url ./ *.html assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*", "build": "rm -rf dist/ && npm run generate && parcel build --public-url ./ *.html assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*",
"prepare-deploy": "npm run test && npm run generate:editor-layer-index && npm run generate:layouts && npm run generate && npm run build && rm -rf .cache", "prepare-deploy": "npm run test && npm run generate:editor-layer-index && npm run generate:layouts && npm run generate && npm run build && rm -rf .cache && npm run generate:docs",
"deploy:staging": "npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/Staging/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/Staging/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", "deploy:staging": "npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/Staging/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/Staging/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean",
"deploy:pietervdvn": "npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/MapComplete/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/MapComplete/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", "deploy:pietervdvn": "npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/MapComplete/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/MapComplete/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean",
"deploy:production": "rm -rf ./assets/generated && npm run prepare-deploy && npm run optimize-images && rm -rf /home/pietervdvn/git/mapcomplete.github.io/* && cp -r dist/* /home/pietervdvn/git/mapcomplete.github.io/ && cd /home/pietervdvn/git/mapcomplete.github.io/ && echo \"mapcomplete.osm.be\" > CNAME && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", "deploy:production": "rm -rf ./assets/generated && npm run prepare-deploy && npm run optimize-images && rm -rf /home/pietervdvn/git/mapcomplete.github.io/* && cp -r dist/* /home/pietervdvn/git/mapcomplete.github.io/ && cd /home/pietervdvn/git/mapcomplete.github.io/ && echo \"mapcomplete.osm.be\" > CNAME && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean",
@ -38,6 +39,7 @@
"@types/leaflet-providers": "^1.2.0", "@types/leaflet-providers": "^1.2.0",
"@types/leaflet.markercluster": "^1.4.3", "@types/leaflet.markercluster": "^1.4.3",
"@types/lz-string": "^1.3.34", "@types/lz-string": "^1.3.34",
"@types/prompt-sync": "^4.1.0",
"autoprefixer": "^9.8.6", "autoprefixer": "^9.8.6",
"country-language": "^0.1.7", "country-language": "^0.1.7",
"email-validator": "^2.0.4", "email-validator": "^2.0.4",
@ -58,6 +60,7 @@
"osmtogeojson": "^3.0.0-beta.4", "osmtogeojson": "^3.0.0-beta.4",
"parcel": "^1.2.4", "parcel": "^1.2.4",
"postcss": "^7.0.35", "postcss": "^7.0.35",
"prompt-sync": "^4.2.0",
"sharp": "^0.27.0", "sharp": "^0.27.0",
"slick-carousel": "^1.8.1", "slick-carousel": "^1.8.1",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.2", "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.2",

View file

@ -0,0 +1,147 @@
import {Utils} from "../Utils";
Utils.runningFromConsole = true;
import {existsSync, mkdirSync, readdirSync, readFileSync, writeFile, writeFileSync, lstatSync} from "fs";
import {LicenseInfo} from "../Logic/Web/Wikimedia";
import {icon, Icon} from "leaflet";
interface SmallLicense {
path: string,
authors: string[],
license: string,
sources: string[]
}
/**
* Sweeps the entire 'assets/' (except assets/generated) directory for image files and any 'license_info.json'-file.
* Checks that the license info is included for each of them and generates a compiles license_info.json for those
*/
function readDirRecSync(path): string[] {
const result = []
for (const entry of readdirSync(path)) {
const fullEntry = path + "/" + entry
const stats = lstatSync(fullEntry)
if (stats.isDirectory()) {
// Subdirectory
// @ts-ignore
result.push(...readDirRecSync(fullEntry))
} else {
result.push(fullEntry)
}
}
return result;
}
function generateLicenseInfos(paths: string[]): SmallLicense[] {
const licenses = []
for (const path of paths) {
console.log("Reading info from " + path)
const parsed = JSON.parse(readFileSync(path, "UTF-8"))
if (Array.isArray(parsed)) {
const l: SmallLicense[] = parsed
for (const smallLicens of l) {
smallLicens.path = path.substring(0, path.length - "license_info.json".length) + smallLicens.path
}
licenses.push(...l)
} else {
const smallLicens: SmallLicense = parsed;
smallLicens.path = path.substring(0, 1 + path.lastIndexOf("/")) + smallLicens.path
licenses.push(smallLicens)
}
}
return licenses
}
function missingLicenseInfos(licenseInfos: SmallLicense[], allIcons: string[]) {
const missing = []
const knownPaths = new Set<string>()
for (const licenseInfo of licenseInfos) {
knownPaths.add(licenseInfo.path)
}
for (const iconPath of allIcons) {
if (iconPath.indexOf("license_info.json") >= 0) {
continue;
}
if (knownPaths.has(iconPath)) {
continue;
}
missing.push(iconPath)
}
return missing;
}
const prompt = require('prompt-sync')();
function promptLicenseFor(path): SmallLicense {
const author = prompt("What is the author for artwork " + path + "? (me == Pieter Vander Vennet/CC0, Q to quit) > ")
path = path.substring(path.lastIndexOf("/") + 1)
if (author == "me") {
return {
authors: ["Pieter Vander Vennet"],
path: path,
license: "CC0",
sources: []
}
}
if (author == "cf") {
return {
authors: ["Pieter Fiers", "Thibault Declercq", "Pierre Barban", "Joost Schouppe","Pieter Vander Vennet"],
path: path,
license: "CC-BY-SA",
sources: ["https://osoc.be/editions/2020/cyclofix"]
}
}
if (author == "gitte") {
return {
authors: ["Gitte Vande Graveele"],
path: path,
license: "CC-BY-SA",
sources: ["https://osoc.be/editions/2020/walk-by-brussels"]
}
}
if(author == "s"){
return null;
}
if (author == "Q" || author == "q" || author == "") {
throw "Quitting now!"
}
return {
authors: author.split(";"),
path: path,
license: prompt("What is the license for artwork " + path + "? > "),
sources: prompt("Where was this artwork found? > ").split(";")
}
}
function createLicenseInfoFor(path): void {
const li = promptLicenseFor(path);
if(li == null){
return;
}
writeFileSync(path + ".license_info.json", JSON.stringify(li, null, " "))
}
console.log("Checking and compiling license info")
const contents = readDirRecSync("./assets")
.filter(entry => entry.indexOf("./assets/generated") != 0)
const licensePaths = contents.filter(entry => entry.indexOf("license_info.json") >= 0)
const licenseInfos = generateLicenseInfos(licensePaths);
writeFileSync("./assets/generated/license_info.json", JSON.stringify(licenseInfos, null, " "))
const artwork = contents.filter(pth => pth.match(/(.svg|.png|.jpg)$/i) != null)
const missingLicenses = missingLicenseInfos(licenseInfos, artwork)
console.log(`There are ${missingLicenses.length} licenses missing.`)
let i = 1;
for (const missingLicens of missingLicenses) {
console.log(i + " / " + missingLicenses.length)
createLicenseInfoFor(missingLicens)
i++;
}