| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  | import ScriptUtils from "./ScriptUtils"; | 
					
						
							|  |  |  | import {Utils} from "../Utils"; | 
					
						
							|  |  |  | import {lstatSync, readdirSync, readFileSync, writeFileSync} from "fs"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Utils.runningFromConsole = true | 
					
						
							|  |  |  | import LayerConfig from "../Customizations/JSON/LayerConfig"; | 
					
						
							|  |  |  | import {error} from "util"; | 
					
						
							|  |  |  | import * as licenses from "../assets/generated/license_info.json" | 
					
						
							|  |  |  | import SmallLicense from "../Models/smallLicense"; | 
					
						
							|  |  |  | import LayoutConfig from "../Customizations/JSON/LayoutConfig"; | 
					
						
							| 
									
										
										
										
											2021-04-10 03:50:44 +02:00
										 |  |  | import {LayerConfigJson} from "../Customizations/JSON/LayerConfigJson"; | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  | import {Layer} from "leaflet"; | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  | // This scripts scans 'assets/layers/*.json' for layer definition files and 'assets/themes/*.json' for theme definition files.
 | 
					
						
							|  |  |  | // It spits out an overview of those to be used to load them
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // First, remove the old file. It might be buggy!
 | 
					
						
							|  |  |  | writeFileSync("./assets/generated/known_layers_and_themes.json", JSON.stringify({ | 
					
						
							|  |  |  |     "layers": [], | 
					
						
							|  |  |  |     "themes": [] | 
					
						
							|  |  |  | })) | 
					
						
							|  |  |  | const layerFiles = ScriptUtils.readDirRecSync("./assets/layers") | 
					
						
							|  |  |  |     .filter(path => path.indexOf(".json") > 0) | 
					
						
							|  |  |  |     .filter(path => path.indexOf("license_info.json") < 0) | 
					
						
							|  |  |  |     .map(path => { | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             const parsed = JSON.parse(readFileSync(path, "UTF8")); | 
					
						
							|  |  |  |             return parsed | 
					
						
							|  |  |  |         } catch (e) { | 
					
						
							|  |  |  |             console.error("Could not parse file ", path, "due to ", e) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }) | 
					
						
							| 
									
										
										
										
											2021-04-10 03:50:44 +02:00
										 |  |  | const themeFiles: any[] = ScriptUtils.readDirRecSync("./assets/themes") | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |     .filter(path => path.indexOf(".json") > 0) | 
					
						
							|  |  |  |     .filter(path => path.indexOf("license_info.json") < 0) | 
					
						
							|  |  |  |     .map(path => { | 
					
						
							|  |  |  |         return JSON.parse(readFileSync(path, "UTF8")); | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  | writeFileSync("./assets/generated/known_layers_and_themes.json", JSON.stringify({ | 
					
						
							|  |  |  |     "layers": layerFiles, | 
					
						
							|  |  |  |     "themes": themeFiles | 
					
						
							|  |  |  | })) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | console.log("Discovered ", layerFiles.length, "layers and ", themeFiles.length, "themes\n") | 
					
						
							|  |  |  | console.log("   ---------- VALIDATING ---------") | 
					
						
							|  |  |  | // ------------- VALIDATION --------------
 | 
					
						
							|  |  |  | const licensePaths = [] | 
					
						
							|  |  |  | for (const i in licenses) { | 
					
						
							|  |  |  |     licensePaths.push(licenses[i].path) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | const knownPaths = new Set<string>(licensePaths) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  | function validateLayer(layerJson: LayerConfigJson, context?: string): string[] { | 
					
						
							|  |  |  |     let errorCount = []; | 
					
						
							| 
									
										
										
										
											2021-04-10 03:50:44 +02:00
										 |  |  |     if (layerJson["overpassTags"] !== undefined) { | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  |         errorCount.push("CRIT! Layer ", layerJson.id, "still uses the old 'overpassTags'-format. Please use 'source: {osmTags: <tags>}' instead") | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-04-10 03:50:44 +02:00
										 |  |  |     try { | 
					
						
							|  |  |  |         const layer = new LayerConfig(layerJson, "test", true) | 
					
						
							|  |  |  |         const images = Array.from(layer.ExtractImages()) | 
					
						
							|  |  |  |         const remoteImages = images.filter(img => img.indexOf("http") == 0) | 
					
						
							|  |  |  |         for (const remoteImage of remoteImages) { | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  |             errorCount.push("Found a remote image: "+ remoteImage+ " in layer "+ layer.id) | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-04-10 03:50:44 +02:00
										 |  |  |         for (const image of images) { | 
					
						
							|  |  |  |             if (!knownPaths.has(image)) { | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  |                 const ctx = context === undefined ? "" : ` in a layer defined in the theme ${context}` | 
					
						
							|  |  |  |                 errorCount.push(`Image with path ${image} not found or not attributed; it is used in ${layer.id}${ctx}`) | 
					
						
							| 
									
										
										
										
											2021-04-10 03:50:44 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-04-10 14:25:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-10 03:50:44 +02:00
										 |  |  |     } catch (e) { | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  |         return [`Layer ${layerJson.id}` ?? JSON.stringify(layerJson).substring(0, 50)+" is invalid: "+ e] | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     return errorCount | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-04-10 03:50:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  | let layerErrorCount = [] | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  | const knownLayerIds = new Set<string>(); | 
					
						
							|  |  |  | for (const layerFile of layerFiles) { | 
					
						
							|  |  |  |     knownLayerIds.add(layerFile.id) | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  |     layerErrorCount .push(...validateLayer(layerFile)) | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  | let themeErrorCount = [] | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  | for (const themeFile of themeFiles) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const layer of themeFile.layers) { | 
					
						
							| 
									
										
										
										
											2021-04-10 03:50:44 +02:00
										 |  |  |         if (typeof layer === "string") { | 
					
						
							|  |  |  |             if (!knownLayerIds.has(layer)) { | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  |                 themeErrorCount.push("Unknown layer id: "+ layer) | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-04-10 15:53:47 +02:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             if (layer.builtin !== undefined) { | 
					
						
							|  |  |  |                 if (!knownLayerIds.has(layer.builtin)) { | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  |                     themeErrorCount.push("Unknown layer id: "+ layer.builtin+ "(which uses inheritance)") | 
					
						
							| 
									
										
										
										
											2021-04-10 15:53:47 +02:00
										 |  |  |                 }  | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 // layer.builtin contains layer overrides - we can skip those
 | 
					
						
							| 
									
										
										
										
											2021-04-10 16:06:01 +02:00
										 |  |  |                 layerErrorCount .push(...validateLayer(layer, themeFile.id)) | 
					
						
							| 
									
										
										
										
											2021-04-10 15:53:47 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-04-10 03:50:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-10 15:53:47 +02:00
										 |  |  |     themeFile.layers = themeFile.layers | 
					
						
							|  |  |  |         .filter(l => typeof l != "string") // We remove all the builtin layer references as they don't work with ts-node for some weird reason
 | 
					
						
							|  |  |  |         .filter(l => l.builtin === undefined) | 
					
						
							| 
									
										
										
										
											2021-04-10 03:50:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |     try { | 
					
						
							| 
									
										
										
										
											2021-04-10 03:50:44 +02:00
										 |  |  |         const theme = new LayoutConfig(themeFile, true, "test") | 
					
						
							| 
									
										
										
										
											2021-04-10 14:25:06 +02:00
										 |  |  |         if (theme.id !== theme.id.toLowerCase()) { | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  |             themeErrorCount.push("Theme ids should be in lowercase, but it is "+ theme.id) | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } catch (e) { | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  |         themeErrorCount.push("Could not parse theme "+ themeFile["id"]+ "due to", e) | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-04-10 16:06:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | console.log("LE", layerErrorCount) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  | if (layerErrorCount.length + themeErrorCount.length == 0) { | 
					
						
							| 
									
										
										
										
											2021-04-10 14:25:06 +02:00
										 |  |  |     console.log("All good!") | 
					
						
							|  |  |  | } else { | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  |     const errors = layerErrorCount.concat(themeErrorCount).join("\n") | 
					
						
							|  |  |  |     console.log(errors) | 
					
						
							|  |  |  |     const msg = (`Found ${errors.length} errors in the layers; ${themeErrorCount} errors in the themes`) | 
					
						
							|  |  |  |     if(process.argv.indexOf("--no-fail") >= 0) { | 
					
						
							| 
									
										
										
										
											2021-04-10 15:01:28 +02:00
										 |  |  |         console.log(msg) | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  |     }else if(process.argv.indexOf("--report") >= 0){ | 
					
						
							| 
									
										
										
										
											2021-04-10 16:06:01 +02:00
										 |  |  |         writeFileSync("layer_report.txt", errors) | 
					
						
							| 
									
										
										
										
											2021-04-10 15:01:28 +02:00
										 |  |  |     }else{ | 
					
						
							| 
									
										
										
										
											2021-04-10 16:01:14 +02:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2021-04-10 15:01:28 +02:00
										 |  |  |         throw msg; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-04-10 14:25:06 +02:00
										 |  |  | } |