| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import * as fs from "fs" | 
					
						
							|  |  |  | import { existsSync, lstatSync, readdirSync, readFileSync } from "fs" | 
					
						
							|  |  |  | import { Utils } from "../Utils" | 
					
						
							|  |  |  | import * as https from "https" | 
					
						
							|  |  |  | import { LayoutConfigJson } from "../Models/ThemeConfig/Json/LayoutConfigJson" | 
					
						
							|  |  |  | import { LayerConfigJson } from "../Models/ThemeConfig/Json/LayerConfigJson" | 
					
						
							|  |  |  | import xml2js from "xml2js" | 
					
						
							| 
									
										
										
										
											2022-05-26 13:23:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  | export default class ScriptUtils { | 
					
						
							| 
									
										
										
										
											2021-06-22 14:21:32 +02:00
										 |  |  |     public static fixUtils() { | 
					
						
							| 
									
										
										
										
											2022-05-26 13:23:25 +02:00
										 |  |  |         Utils.externalDownloadFunction = ScriptUtils.Download | 
					
						
							| 
									
										
										
										
											2021-06-22 14:21:32 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-20 12:27:33 +02:00
										 |  |  |     public static readDirRecSync(path, maxDepth = 999): string[] { | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |         const result = [] | 
					
						
							| 
									
										
										
										
											2021-06-22 14:21:32 +02:00
										 |  |  |         if (maxDepth <= 0) { | 
					
						
							| 
									
										
										
										
											2021-05-20 12:27:33 +02:00
										 |  |  |             return [] | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |         for (const entry of readdirSync(path)) { | 
					
						
							|  |  |  |             const fullEntry = path + "/" + entry | 
					
						
							|  |  |  |             const stats = lstatSync(fullEntry) | 
					
						
							|  |  |  |             if (stats.isDirectory()) { | 
					
						
							|  |  |  |                 // Subdirectory
 | 
					
						
							|  |  |  |                 // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2021-05-20 12:27:33 +02:00
										 |  |  |                 result.push(...ScriptUtils.readDirRecSync(fullEntry, maxDepth - 1)) | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |             } else { | 
					
						
							|  |  |  |                 result.push(fullEntry) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return result | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-05-14 17:37:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-22 14:21:32 +02:00
										 |  |  |     public static DownloadFileTo(url, targetFilePath: string): void { | 
					
						
							|  |  |  |         console.log("Downloading ", url, "to", targetFilePath) | 
					
						
							|  |  |  |         https.get(url, (res) => { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const filePath = fs.createWriteStream(targetFilePath) | 
					
						
							|  |  |  |             res.pipe(filePath) | 
					
						
							|  |  |  |             filePath.on("finish", () => { | 
					
						
							|  |  |  |                 filePath.close() | 
					
						
							|  |  |  |                 console.log("Download Completed") | 
					
						
							| 
									
										
										
										
											2021-06-22 14:21:32 +02:00
										 |  |  |             }) | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-04 18:59:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-27 15:06:36 +02:00
										 |  |  |     public static erasableLog(...text) { | 
					
						
							| 
									
										
										
										
											2021-09-04 18:59:51 +02:00
										 |  |  |         process.stdout.write("\r " + text.join(" ") + "                \r") | 
					
						
							| 
									
										
										
										
											2021-07-27 15:06:36 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-04-22 03:30:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public static sleep(ms) { | 
					
						
							| 
									
										
										
										
											2021-05-14 17:37:21 +02:00
										 |  |  |         if (ms <= 0) { | 
					
						
							| 
									
										
										
										
											2021-05-14 02:25:30 +02:00
										 |  |  |             process.stdout.write("\r                                       \r") | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2021-05-14 02:25:30 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-04-22 03:30:46 +02:00
										 |  |  |         return new Promise((resolve) => { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             process.stdout.write("\r Sleeping for " + ms / 1000 + "s \r") | 
					
						
							|  |  |  |             setTimeout(resolve, 1000) | 
					
						
							|  |  |  |         }).then(() => ScriptUtils.sleep(ms - 1000)) | 
					
						
							| 
									
										
										
										
											2021-04-22 03:30:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 13:58:56 +02:00
										 |  |  |     public static getLayerPaths(): string[] { | 
					
						
							|  |  |  |         return ScriptUtils.readDirRecSync("./assets/layers") | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             .filter((path) => path.indexOf(".json") > 0) | 
					
						
							|  |  |  |             .filter((path) => path.indexOf(".proto.json") < 0) | 
					
						
							|  |  |  |             .filter((path) => path.indexOf("license_info.json") < 0) | 
					
						
							| 
									
										
										
										
											2022-07-06 13:58:56 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     public static getLayerFiles(): { parsed: LayerConfigJson; path: string }[] { | 
					
						
							| 
									
										
										
										
											2021-05-19 23:31:00 +02:00
										 |  |  |         return ScriptUtils.readDirRecSync("./assets/layers") | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             .filter((path) => path.indexOf(".json") > 0) | 
					
						
							|  |  |  |             .filter((path) => path.indexOf(".proto.json") < 0) | 
					
						
							|  |  |  |             .filter((path) => path.indexOf("license_info.json") < 0) | 
					
						
							|  |  |  |             .map((path) => { | 
					
						
							| 
									
										
										
										
											2021-05-19 23:31:00 +02:00
										 |  |  |                 try { | 
					
						
							| 
									
										
										
										
											2021-07-07 15:19:05 +02:00
										 |  |  |                     const contents = readFileSync(path, "UTF8") | 
					
						
							| 
									
										
										
										
											2021-09-04 18:59:51 +02:00
										 |  |  |                     if (contents === "") { | 
					
						
							|  |  |  |                         throw "The file " + path + " is empty, did you properly save?" | 
					
						
							| 
									
										
										
										
											2021-07-07 15:19:05 +02:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2021-09-04 18:59:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     const parsed = JSON.parse(contents) | 
					
						
							|  |  |  |                     return { parsed, path } | 
					
						
							| 
									
										
										
										
											2021-05-19 23:31:00 +02:00
										 |  |  |                 } catch (e) { | 
					
						
							|  |  |  |                     console.error("Could not parse file ", "./assets/layers/" + path, "due to ", e) | 
					
						
							| 
									
										
										
										
											2022-07-01 02:41:09 +02:00
										 |  |  |                     throw e | 
					
						
							| 
									
										
										
										
											2021-05-19 23:31:00 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 13:58:56 +02:00
										 |  |  |     public static getThemePaths(): string[] { | 
					
						
							| 
									
										
										
										
											2021-05-19 23:31:00 +02:00
										 |  |  |         return ScriptUtils.readDirRecSync("./assets/themes") | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             .filter((path) => path.endsWith(".json") && !path.endsWith(".proto.json")) | 
					
						
							|  |  |  |             .filter((path) => path.indexOf("license_info.json") < 0) | 
					
						
							| 
									
										
										
										
											2022-07-06 13:58:56 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     public static getThemeFiles(): { parsed: LayoutConfigJson; path: string }[] { | 
					
						
							|  |  |  |         return this.getThemePaths().map((path) => { | 
					
						
							|  |  |  |             try { | 
					
						
							|  |  |  |                 const contents = readFileSync(path, "UTF8") | 
					
						
							|  |  |  |                 if (contents === "") { | 
					
						
							|  |  |  |                     throw "The file " + path + " is empty, did you properly save?" | 
					
						
							| 
									
										
										
										
											2021-05-19 23:31:00 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 const parsed = JSON.parse(contents) | 
					
						
							|  |  |  |                 return { parsed: parsed, path: path } | 
					
						
							|  |  |  |             } catch (e) { | 
					
						
							|  |  |  |                 console.error("Could not read file ", path, "due to ", e) | 
					
						
							|  |  |  |                 throw e | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2021-05-19 23:31:00 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 01:18:57 +02:00
										 |  |  |     public static TagInfoHistogram(key: string): Promise<{ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         data: { count: number; value: string; fraction: number }[] | 
					
						
							| 
									
										
										
										
											2021-09-13 01:18:57 +02:00
										 |  |  |     }> { | 
					
						
							|  |  |  |         const url = `https://taginfo.openstreetmap.org/api/4/key/values?key=${key}&filter=all&lang=en&sortname=count&sortorder=desc&page=1&rp=17&qtype=value` | 
					
						
							|  |  |  |         return ScriptUtils.DownloadJSON(url) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 13:58:56 +02:00
										 |  |  |     public static async ReadSvg(path: string): Promise<any> { | 
					
						
							|  |  |  |         if (!existsSync(path)) { | 
					
						
							|  |  |  |             throw "File not found: " + path | 
					
						
							| 
									
										
										
										
											2022-03-08 04:09:03 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-07-06 13:58:56 +02:00
										 |  |  |         const root = await xml2js.parseStringPromise(readFileSync(path, "UTF8")) | 
					
						
							| 
									
										
										
										
											2022-02-10 23:10:39 +01:00
										 |  |  |         return root.svg | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-11 01:49:07 +02:00
										 |  |  |     public static ReadSvgSync(path: string, callback: (svg: any) => void): any { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         xml2js.parseString(readFileSync(path, "UTF8"), { async: false }, (err, root) => { | 
					
						
							| 
									
										
										
										
											2022-07-06 13:58:56 +02:00
										 |  |  |             if (err) { | 
					
						
							|  |  |  |                 throw err | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             callback(root["svg"]) | 
					
						
							| 
									
										
										
										
											2022-07-06 13:58:56 +02:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-02-10 23:10:39 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-07-06 13:58:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private static async DownloadJSON(url: string, headers?: any): Promise<any> { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const data = await ScriptUtils.Download(url, headers) | 
					
						
							| 
									
										
										
										
											2022-07-06 13:58:56 +02:00
										 |  |  |         return JSON.parse(data.content) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private static Download(url, headers?: any): Promise<{ content: string }> { | 
					
						
							|  |  |  |         return new Promise((resolve, reject) => { | 
					
						
							|  |  |  |             try { | 
					
						
							|  |  |  |                 headers = headers ?? {} | 
					
						
							|  |  |  |                 headers.accept = "application/json" | 
					
						
							|  |  |  |                 console.log(" > ScriptUtils.DownloadJson(", url, ")") | 
					
						
							|  |  |  |                 const urlObj = new URL(url) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 https.get( | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         host: urlObj.host, | 
					
						
							|  |  |  |                         path: urlObj.pathname + urlObj.search, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         port: urlObj.port, | 
					
						
							|  |  |  |                         headers: headers, | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                     (res) => { | 
					
						
							|  |  |  |                         const parts: string[] = [] | 
					
						
							|  |  |  |                         res.setEncoding("utf8") | 
					
						
							|  |  |  |                         res.on("data", function (chunk) { | 
					
						
							|  |  |  |                             // @ts-ignore
 | 
					
						
							|  |  |  |                             parts.push(chunk) | 
					
						
							|  |  |  |                         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         res.addListener("end", function () { | 
					
						
							|  |  |  |                             resolve({ content: parts.join("") }) | 
					
						
							|  |  |  |                         }) | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2022-07-06 13:58:56 +02:00
										 |  |  |             } catch (e) { | 
					
						
							|  |  |  |                 reject(e) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-04-10 03:18:32 +02:00
										 |  |  | } |