implementation

pull/2/head
Fionn 2 years ago
parent f81e2c9324
commit 7e67950966

@ -0,0 +1,46 @@
kind: pipeline
type: docker
name: build dev
steps:
- name: build and push image
image: plugins/docker
settings:
dockerfile: Dockerfile
registry: git.fsisp.de
repo: git.fsisp.de/fionn/isasure-wx
username:
from_secret: reg_username
password:
from_secret: reg_password
tags:
- dev
- '${DRONE_COMMIT:0:8}'
trigger:
branch:
- dev
---
kind: pipeline
type: docker
name: build master
steps:
- name: build and push image
image: plugins/docker
settings:
dockerfile: Dockerfile
registry: git.fsisp.de
repo: git.fsisp.de/fionn/isasure-wx
username:
from_secret: reg_username
password:
from_secret: reg_password
tags:
- latest
- '${DRONE_COMMIT:0:8}'
trigger:
branch:
- main

@ -9,10 +9,14 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"express": "^4.18.1" "axios": "^1.3.4",
"express": "^4.18.1",
"morgan": "^1.10.0",
"node-schedule": "^2.1.1"
}, },
"devDependencies": { "devDependencies": {
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/morgan": "^1.9.4",
"@types/node": "^18.7.6", "@types/node": "^18.7.6",
"@typescript-eslint/eslint-plugin": "^5.38.1", "@typescript-eslint/eslint-plugin": "^5.38.1",
"@typescript-eslint/parser": "^5.38.1", "@typescript-eslint/parser": "^5.38.1",
@ -177,6 +181,15 @@
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==",
"dev": true "dev": true
}, },
"node_modules/@types/morgan": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.4.tgz",
"integrity": "sha512-cXoc4k+6+YAllH3ZHmx4hf7La1dzUk6keTR4bF4b4Sc0mZxU/zK4wO7l+ZzezXm/jkYj/qC+uYGZrarZdIVvyQ==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "18.11.18", "version": "18.11.18",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
@ -528,12 +541,43 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz",
"integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true "dev": true
}, },
"node_modules/basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
"dependencies": {
"safe-buffer": "5.1.2"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/basic-auth/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/body-parser": { "node_modules/body-parser": {
"version": "1.20.1", "version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
@ -664,6 +708,17 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true "dev": true
}, },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -708,6 +763,17 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
}, },
"node_modules/cron-parser": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.8.1.tgz",
"integrity": "sha512-jbokKWGcyU4gl6jAfX97E1gDpY12DJ1cLJZmoDzaAln/shZ+S3KBFBuA2Q6WeUN4gJf/8klnV1EfvhA2lK5IRQ==",
"dependencies": {
"luxon": "^3.2.1"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -761,6 +827,14 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/depd": { "node_modules/depd": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@ -1550,6 +1624,38 @@
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
"dev": true "dev": true
}, },
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/forwarded": { "node_modules/forwarded": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@ -2177,6 +2283,11 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true "dev": true
}, },
"node_modules/long-timeout": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz",
"integrity": "sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w=="
},
"node_modules/lru-cache": { "node_modules/lru-cache": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@ -2189,6 +2300,14 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/luxon": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz",
"integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==",
"engines": {
"node": ">=12"
}
},
"node_modules/map-stream": { "node_modules/map-stream": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
@ -2289,6 +2408,45 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/morgan": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
"integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==",
"dependencies": {
"basic-auth": "~2.0.1",
"debug": "2.6.9",
"depd": "~2.0.0",
"on-finished": "~2.3.0",
"on-headers": "~1.0.2"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/morgan/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/morgan/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/morgan/node_modules/on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
"dependencies": {
"ee-first": "1.1.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/ms": { "node_modules/ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -2321,6 +2479,19 @@
"integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==", "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==",
"dev": true "dev": true
}, },
"node_modules/node-schedule": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.1.1.tgz",
"integrity": "sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==",
"dependencies": {
"cron-parser": "^4.2.0",
"long-timeout": "0.1.1",
"sorted-array-functions": "^1.3.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/object-inspect": { "node_modules/object-inspect": {
"version": "1.12.2", "version": "1.12.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
@ -2398,6 +2569,14 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/on-headers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/once": { "node_modules/once": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@ -2563,6 +2742,11 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/ps-tree": { "node_modules/ps-tree": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz",
@ -2902,6 +3086,11 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/sorted-array-functions": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz",
"integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA=="
},
"node_modules/split": { "node_modules/split": {
"version": "0.3.3", "version": "0.3.3",
"resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
@ -3401,6 +3590,15 @@
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==",
"dev": true "dev": true
}, },
"@types/morgan": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.4.tgz",
"integrity": "sha512-cXoc4k+6+YAllH3ZHmx4hf7La1dzUk6keTR4bF4b4Sc0mZxU/zK4wO7l+ZzezXm/jkYj/qC+uYGZrarZdIVvyQ==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/node": { "@types/node": {
"version": "18.11.18", "version": "18.11.18",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
@ -3624,12 +3822,42 @@
"es-shim-unscopables": "^1.0.0" "es-shim-unscopables": "^1.0.0"
} }
}, },
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"axios": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz",
"integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==",
"requires": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"balanced-match": { "balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true "dev": true
}, },
"basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
"requires": {
"safe-buffer": "5.1.2"
},
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
},
"body-parser": { "body-parser": {
"version": "1.20.1", "version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
@ -3737,6 +3965,14 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true "dev": true
}, },
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -3772,6 +4008,14 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
}, },
"cron-parser": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.8.1.tgz",
"integrity": "sha512-jbokKWGcyU4gl6jAfX97E1gDpY12DJ1cLJZmoDzaAln/shZ+S3KBFBuA2Q6WeUN4gJf/8klnV1EfvhA2lK5IRQ==",
"requires": {
"luxon": "^3.2.1"
}
},
"cross-spawn": { "cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -3808,6 +4052,11 @@
"object-keys": "^1.1.1" "object-keys": "^1.1.1"
} }
}, },
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
},
"depd": { "depd": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@ -4435,6 +4684,21 @@
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
"dev": true "dev": true
}, },
"follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
},
"form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
},
"forwarded": { "forwarded": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@ -4875,6 +5139,11 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true "dev": true
}, },
"long-timeout": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz",
"integrity": "sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w=="
},
"lru-cache": { "lru-cache": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@ -4884,6 +5153,11 @@
"yallist": "^4.0.0" "yallist": "^4.0.0"
} }
}, },
"luxon": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz",
"integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg=="
},
"map-stream": { "map-stream": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
@ -4954,6 +5228,41 @@
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
"dev": true "dev": true
}, },
"morgan": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
"integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==",
"requires": {
"basic-auth": "~2.0.1",
"debug": "2.6.9",
"depd": "~2.0.0",
"on-finished": "~2.3.0",
"on-headers": "~1.0.2"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
"requires": {
"ee-first": "1.1.1"
}
}
}
},
"ms": { "ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -4983,6 +5292,16 @@
"integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==", "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==",
"dev": true "dev": true
}, },
"node-schedule": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.1.1.tgz",
"integrity": "sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==",
"requires": {
"cron-parser": "^4.2.0",
"long-timeout": "0.1.1",
"sorted-array-functions": "^1.3.0"
}
},
"object-inspect": { "object-inspect": {
"version": "1.12.2", "version": "1.12.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
@ -5036,6 +5355,11 @@
"ee-first": "1.1.1" "ee-first": "1.1.1"
} }
}, },
"on-headers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
},
"once": { "once": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@ -5156,6 +5480,11 @@
"ipaddr.js": "1.9.1" "ipaddr.js": "1.9.1"
} }
}, },
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"ps-tree": { "ps-tree": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz",
@ -5378,6 +5707,11 @@
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true "dev": true
}, },
"sorted-array-functions": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz",
"integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA=="
},
"split": { "split": {
"version": "0.3.3", "version": "0.3.3",
"resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",

@ -14,10 +14,14 @@
"author": "Fionn Sperath", "author": "Fionn Sperath",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"express": "^4.18.1" "axios": "^1.3.4",
"express": "^4.18.1",
"morgan": "^1.10.0",
"node-schedule": "^2.1.1"
}, },
"devDependencies": { "devDependencies": {
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/morgan": "^1.9.4",
"@types/node": "^18.7.6", "@types/node": "^18.7.6",
"@typescript-eslint/eslint-plugin": "^5.38.1", "@typescript-eslint/eslint-plugin": "^5.38.1",
"@typescript-eslint/parser": "^5.38.1", "@typescript-eslint/parser": "^5.38.1",
@ -30,4 +34,4 @@
"tsc-watch": "^5.0.3", "tsc-watch": "^5.0.3",
"typescript": "^4.7.4" "typescript": "^4.7.4"
} }
} }

@ -1,10 +1,16 @@
import express, { NextFunction, Request, Response } from 'express'; import express, { NextFunction, Request, Response } from 'express';
import nodesched from 'node-schedule';
import morgan from 'morgan';
import router from './router'; import router from './router';
import wxService from './services/wx.service';
const { PORT = 3000 } = process.env; const { PORT = 3000 } = process.env;
const app = express(); const app = express();
app.set('trust proxy', true);
app.use(morgan('combined'));
app.use('/api', router.router); app.use('/api', router.router);
const frontendRoot = '/opt/frontend/dist'; const frontendRoot = '/opt/frontend/dist';
@ -19,6 +25,9 @@ app.use((err, req: Request, res: Response, next: NextFunction) => {
res.status(500).json({ msg: 'an error occurred' }); res.status(500).json({ msg: 'an error occurred' });
}); });
nodesched.scheduleJob('regenerate data', '*/30 * * * * *', wxService.wrappedGenerateData)
wxService.wrappedGenerateData();
app.listen(PORT, () => { app.listen(PORT, () => {
console.log( console.log(
`application is listening on port ${PORT}`, `application is listening on port ${PORT}`,

@ -1,14 +0,0 @@
import { Request, Response } from 'express';
import fooService from '../services/foo.service';
function getFoo(req: Request, res: Response) {
res.json({
foo: true,
msg: fooService.getFooDetails(),
data: req.body,
});
}
export default {
getFoo,
};

@ -0,0 +1,31 @@
import express from 'express';
import regionsService from '../services/regions.service';
export async function getRegions(req: express.Request, res: express.Response, next: express.NextFunction) {
try {
res.json(regionsService.getRegions());
} catch (e) {
next(e);
}
}
export async function getRegion(req: express.Request, res: express.Response, next: express.NextFunction) {
try {
const { region } = req.params;
const regionData = regionsService.getRegion(region);
if(!regionData) {
return next();
}
res.json(regionData);
} catch (e) {
next(e);
}
}
export default {
getRegions,
getRegion,
};

@ -0,0 +1,15 @@
import express from 'express';
import wxService from '../services/wx.service';
export async function getRegionWx(req: express.Request, res: express.Response, next: express.NextFunction) {
try {
const { region } = req.params;
res.json(wxService.getWx(region));
} catch (e) {
next(e);
}
}
export default {
getRegionWx,
};

@ -1,10 +1,13 @@
import { Request, Response, Router } from 'express'; import { Request, Response, Router } from 'express';
import fooController from './controllers/foo.controller';
import regionController from './controllers/region.controller';
import wxController from './controllers/wx.controller';
const router = Router(); const router = Router();
router.get('/foo', fooController.getFoo); router.get('/regions', regionController.getRegions);
// aaaaa router.get('/regions/:region', regionController.getRegion);
router.get('/regions/:region/wx', wxController.getRegionWx);
router.use((req: Request, res: Response) => { router.use((req: Request, res: Response) => {
// 404 // 404

@ -0,0 +1,26 @@
import fs from 'fs';
export interface WxConfig {
regions: WxRegion[];
}
export interface WxRegion {
identifier: string;
fixes: WxFix[];
}
export interface WxFix {
name: string;
lat: number;
lon: number;
}
export function getConfig(): WxConfig {
const data = JSON.parse(fs.readFileSync('/opt/wx-config.json').toString());
return data;
}
export default {
getConfig,
}

@ -1,7 +0,0 @@
function getFooDetails() {
return 'foo';
}
export default {
getFooDetails,
};

@ -0,0 +1,18 @@
import configService, { WxConfig, WxRegion } from "./config.service";
export function getRegions(): WxConfig["regions"] {
return configService.getConfig().regions;
}
export function getRegion(identifier: string): WxRegion | undefined {
const regions = getRegions();
const region = regions.find(rg => rg.identifier == identifier);
return region;
}
export default {
getRegions,
getRegion,
};

@ -0,0 +1,134 @@
import axios from "axios";
import { WxFix } from "./config.service";
import regionsService from "./regions.service";
const cachedData: {[key: string]: WxData} = {};
const qnhLevelMapping = {
200: 390,
250: 340,
300: 300,
400: 240,
500: 180,
600: 140,
700: 100,
850: 50
};
const necessaryDatapoints = [
'winddirection',
'windspeed',
'temperature',
];
const requestedData: string[] = [
'temperature_2m',
'windspeed_10m',
'winddirection_10m',
];
for (const qnh of Object.keys(qnhLevelMapping)) {
for (const necessaryDatapoint of necessaryDatapoints) {
requestedData.push(`${necessaryDatapoint}_${qnh}hPa`);
}
}
interface WxLevelData {
"T(K)": string;
windspeed: string;
windhdg: string;
};
export interface WxFixData {
coords: {
lat: string;
long: string;
};
levels: {
[key: string]: WxLevelData;
}
}
export interface WxData {
info: {
date: string;
datestring: string;
};
data: {
[key: string]: WxFixData;
}
}
export async function getDataAtFix(fix: WxFix, index: number): Promise<WxFixData> {
const response = await axios.get(`https://api.open-meteo.com/v1/forecast?latitude=${fix.lat}&longitude=${fix.lon}&windspeed_unit=kn&forecast_days=1&hourly=${requestedData.join(',')}`);
const hourlyData = response.data.hourly;
const data: WxFixData = {
coords: {
lat: String(fix.lat),
long: String(fix.lon)
},
levels: {}
}
data.levels["0"] = {
"T(K)": String(Number(hourlyData?.[`temperature_2m`]?.[index]) + 273.15),
"windspeed": String(hourlyData?.[`windspeed_10m`]?.[index]),
"windhdg": String(hourlyData?.[`winddirection_10m`]?.[index]),
};
for(const [qnh, fl] of Object.entries(qnhLevelMapping)) {
const temp = Number(hourlyData?.[`temperature_${qnh}hPa`]?.[index]) + 273.15;
const dir = hourlyData?.[`windspeed_${qnh}hPa`]?.[index];
const speed = hourlyData?.[`winddirection_${qnh}hPa`]?.[index];
data.levels[String(fl)] = {
"T(K)": String(temp),
"windspeed": String(speed),
"windhdg": String(dir),
}
}
return data;
}
export async function generateData() {
const regions = regionsService.getRegions();
for (const region of regions) {
const now = new Date();
const regionData: WxData = {
info: {
date: now.toISOString(),
datestring: `${now.getUTCDate()}${now.getUTCHours()}`,
},
data: {}
}
for (const fix of region.fixes) {
regionData.data[fix.name] = await getDataAtFix(fix, now.getUTCHours());
}
cachedData[region.identifier] = regionData;
}
return cachedData;
}
export function wrappedGenerateData() {
generateData().catch((...params) => console.error(...params));
}
export function getWx(region: string): WxData | null {
const data = cachedData[region];
return data;
}
export default {
getWx,
generateData,
wrappedGenerateData,
}

@ -0,0 +1,50 @@
{
"$schema": "./wx-config.schema.json",
"regions": [
{
"identifier": "EDGG",
"fixes": [
{
"name": "DKB",
"lat": 49.142753,
"lon": 10.238306
},
{
"name": "DUS",
"lat": 51.283189,
"lon": 6.753725
},
{
"name": "NATOR",
"lat": 48.17,
"lon": 8.321261
},
{
"name": "RASPU",
"lat": 50.072778,
"lon": 10.098611
},
{
"name": "PAD",
"lat": 51.610178,
"lon": 8.618653
}
]
},
{
"identifier": "LOVV",
"fixes": [
{
"name": "VATET",
"lat": 47.600953,
"lon": 14.033119
},
{
"name": "LNZ",
"lat": 48.229711,
"lon": 14.103156
}
]
}
]
}

@ -0,0 +1,44 @@
{
"$id": "https://wx.dotfionn.de/wx-config.schema.json",
"title": "WX-Config",
"description": "The configuration file",
"type": "object",
"properties": {
"regions": {
"description": "The unique identifier for a product",
"type": "array",
"items": {
"type": "object",
"properties": {
"identifier": {
"type": "string",
"description": "e.g. the FIR identifier, e.g. EDGG, EDWW, EDMM, LOVV, ..."
},
"fixes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "identifier of the waypoint/fix"
},
"lat": {
"type": "number",
"description": "latitude of the waypoint"
},
"lon": {
"type": "number",
"description": "longitude of the waypoint"
}
},
"required": ["name", "lat", "lon"]
}
}
}
},
"required": ["identifier", "fixes"]
}
},
"required": [ "regions" ]
}
Loading…
Cancel
Save