From 628855b5d92fc9400375ada394d6168d272f8cdd Mon Sep 17 00:00:00 2001 From: Christopher Hase Date: Thu, 17 Apr 2025 14:46:32 +0200 Subject: [PATCH] add config.json again --- backend/broker.ts | 29 +++++---- dist/backend/broker.js | 137 +++++++++++++++++++++++++++++++++++++++ dist/backend/config.json | 5 ++ dist/backend/server.js | 15 +++++ dist/frontend/deploy.js | 1 + dist/frontend/event.mjs | 18 +++++ dist/frontend/index.html | 67 +++++++++++++++++++ start-local.sh | 7 +- 8 files changed, 266 insertions(+), 13 deletions(-) create mode 100644 dist/backend/broker.js create mode 100644 dist/backend/config.json create mode 100644 dist/backend/server.js create mode 100644 dist/frontend/deploy.js create mode 100644 dist/frontend/event.mjs create mode 100644 dist/frontend/index.html diff --git a/backend/broker.ts b/backend/broker.ts index fc012a3..e672cb6 100644 --- a/backend/broker.ts +++ b/backend/broker.ts @@ -1,13 +1,15 @@ import { exec } from 'child_process'; import * as fs from 'fs'; import * as nodemailer from 'nodemailer'; +import { fileURLToPath } from 'url'; +import * as path from 'path'; // Config for scheduling the next time the main process (sending of horoscope) is run -/*interface Config { +interface Config { emailReceiver: string; mailHost: string; mailPort: number; -}*/ +} // Node structure for the Parse Tree (it's a degenerated tree with one or zero children per node) interface Node { @@ -16,7 +18,7 @@ interface Node { value?: string; } -//var config : Config; +var config : Config; export function executeCommand(): void { @@ -35,9 +37,9 @@ export function executeCommand(): void { } //Load config once - /*if (config == undefined) { + if (config == undefined) { config = loadConfig(); - } */ + } console.log(`Horoscope received; sending E-Mail next`); sendEmail(stdout); @@ -48,28 +50,33 @@ export function executeCommand(): void { executeCommand(); // Load the Configuration -/*function loadConfig(): Config { +function loadConfig(): Config { console.log(`Load Config`); - const data = fs.readFileSync('config.json', 'utf-8'); + const __filename = fileURLToPath(import.meta.url); + const __dirname = path.dirname(__filename); + const configPath = path.join(__dirname, 'config.json'); + + const data = fs.readFileSync(configPath, 'utf-8'); + return JSON.parse(data); -}*/ +} // Send E-Mail async function sendEmail(content: string) { // Create Transporter const transporter = nodemailer.createTransport({ - host: "mailhog.mailhog.svc.cluster.local", //config.mailHost, - port: 1025, //config.mailPort, + host: config.mailHost, //"mailhog.mailhog.svc.cluster.local", //config.mailHost, + port: config.mailPort, //1025, //config.mailPort, secure: false }); try { const info = await transporter.sendMail({ from: '"The Oracle" ', - to: "test@mailhog.local", //config.emailReceiver, + to: config.emailReceiver, //"test@mailhog.local", //config.emailReceiver, subject: "Your Horoscope Is Ready", text: content, html: html(content) diff --git a/dist/backend/broker.js b/dist/backend/broker.js new file mode 100644 index 0000000..3977cc9 --- /dev/null +++ b/dist/backend/broker.js @@ -0,0 +1,137 @@ +import { exec } from 'child_process'; +import * as fs from 'fs'; +import * as nodemailer from 'nodemailer'; +import { fileURLToPath } from 'url'; +import * as path from 'path'; +var config; +export function executeCommand() { + exec('iching divine', (error, stdout, stderr) => { + console.log(`I-Ching-Broker: \'iching divine\' called`); + if (error) { + console.error(`Error: ${error.message}`); + return; + } + if (stderr) { + console.error(`Stderr: ${stderr}`); + return; + } + //Load config once + if (config == undefined) { + config = loadConfig(); + } + console.log(`Horoscope received; sending E-Mail next`); + sendEmail(stdout); + }); +} +// Run function once initially, called from Dockerfile +executeCommand(); +// Load the Configuration +function loadConfig() { + console.log(`Load Config`); + //const data = fs.readFileSync('config.json', 'utf-8'); + //const configPath = path.join(__dirname, 'config.json'); + const __filename = fileURLToPath(import.meta.url); + const __dirname = path.dirname(__filename); + const configPath = path.join(__dirname, 'config.json'); + const data = fs.readFileSync(configPath, 'utf-8'); + return JSON.parse(data); +} +// Send E-Mail +async function sendEmail(content) { + // Create Transporter + const transporter = nodemailer.createTransport({ + host: config.mailHost, //"mailhog.mailhog.svc.cluster.local", //config.mailHost, + port: config.mailPort, //1025, //config.mailPort, + secure: false + }); + try { + const info = await transporter.sendMail({ + from: '"The Oracle" ', + to: config.emailReceiver, //"test@mailhog.local", //config.emailReceiver, + subject: "Your Horoscope Is Ready", + text: content, + html: html(content) + }); + console.log("E-Mail sent: ", info.messageId + "\n\n"); + } + catch (error) { + console.error("Error Sending E-Mail:", error + "\n\n"); + console.log("Failed to send this horoscope: \n", content + "\n"); + } +} +// Generate 1) Parse Tree and 2) HTML +export function html(inputText) { + const parseTree = parse(inputText); + const htmlOutput = render(parseTree); + return htmlOutput; +} +// Generate the Parse Tree +function parse(input) { + console.log("Parse input text"); + const root = { type: "Root" }; + var currentNode = root; + const lines = input.split("\n"); + for (const line of lines) { + if (line.startsWith("Hexagram")) { + const hexagram = { type: "Hexagram" }; + currentNode.child = hexagram; + currentNode = hexagram; + currentNode.value = "

" + line + "

"; + } + else if (line.startsWith("Judgement")) { + const judgement = { type: "Judgement" }; + currentNode.child = judgement; + currentNode = judgement; + currentNode.value = "

" + line + "

"; + } + else if (line.startsWith("Images")) { + const images = { type: "Images" }; + currentNode.child = images; + currentNode = images; + currentNode.value = "

" + line + "

"; + } + else if (line.startsWith("~") && currentNode.type != "ChangingLines") { + const changingLines = { type: "ChangingLines" }; + currentNode.child = changingLines; + currentNode = changingLines; + currentNode.value = line; + } + else { + currentNode.value = currentNode.value + line + "
"; + } + } + return root; +} +// Generate HTML from Parse Tree +function render(node) { + if (node == undefined) { + console.log("I-Ching-Broker: Rendering of nodes finished!"); + return ""; + } + var outputHTML = ""; + switch (node.type) { + case "Root": + return render(node.child); + case "Hexagram": + node.value = node.value?.replace("

", "

"); + node.value = node.value?.replace("

", "

"); + node.value = node.value?.replace("
", " - "); + outputHTML = "

" + node.value + "

"; + outputHTML = outputHTML + render(node.child); + return outputHTML; + case "Images": + outputHTML = "

" + node.value + "

"; //EXTRA closing div (was opened at beginning of hexagram) + outputHTML = outputHTML + render(node.child); + return outputHTML; + case "ChangingLines": + const regex = new RegExp("~", "g"); + node.value = node.value?.replace(regex, ""); + outputHTML = "

" + node.value + "


"; + outputHTML = outputHTML + render(node.child); + return outputHTML; + default: + outputHTML = "

" + node.value + "

"; + outputHTML = outputHTML + render(node.child); + return outputHTML; + } +} diff --git a/dist/backend/config.json b/dist/backend/config.json new file mode 100644 index 0000000..121311d --- /dev/null +++ b/dist/backend/config.json @@ -0,0 +1,5 @@ +{ + "emailReceiver": "test@mailhog.local", + "mailHost": "mailhog.mailhog.svc.cluster.local", + "mailPort": 1025 +} \ No newline at end of file diff --git a/dist/backend/server.js b/dist/backend/server.js new file mode 100644 index 0000000..b0f87f6 --- /dev/null +++ b/dist/backend/server.js @@ -0,0 +1,15 @@ +import express from 'express'; +import cors from 'cors'; +import { executeCommand } from './broker.js'; +const app = express(); +const port = 8090; +app.use(cors()); +app.post('/iching/api/command', (req, res) => { + //TODO no logging from inside this method??? + console.log(`Backend-Server: receiving POST to /iching/api/command`); + executeCommand(); + res.status(200).send('Backend-Server: Broker was called\n'); +}); +app.listen(port, '0.0.0.0', () => { + console.log(`Backend-Server running on http://0.0.0.0:${port}`); +}); diff --git a/dist/frontend/deploy.js b/dist/frontend/deploy.js new file mode 100644 index 0000000..402c906 --- /dev/null +++ b/dist/frontend/deploy.js @@ -0,0 +1 @@ +window.DEPLOY_MODE = 'local'; diff --git a/dist/frontend/event.mjs b/dist/frontend/event.mjs new file mode 100644 index 0000000..c0fa2db --- /dev/null +++ b/dist/frontend/event.mjs @@ -0,0 +1,18 @@ +"use strict"; +function handleClick() { + console.log("Der Button wurde geklickt!"); + //const deployMode = (window as { DEPLOY_MODE?: 'docker' | 'k8s' }).DEPLOY_MODE ?? 'k8s'; + const deployMode = window.DEPLOY_MODE ?? 'k8s'; + const endpoint = deployMode === 'docker' || deployMode === 'local' + ? 'http://localhost:8090/iching/api/command' + : '/iching/api/command'; + console.log(`DEPLOY_MODE=${deployMode}, sende POST an: ${endpoint}`); + fetch(endpoint, { method: 'POST' }) + .then(res => res.text()) + .then(text => console.log("HTTP-Server says:", text)) + .catch(error => console.error("HTTP-Server - Error:", error)); +} +document.addEventListener("DOMContentLoaded", () => { + const button = document.getElementById("myButton"); + button?.addEventListener("click", handleClick); +}); diff --git a/dist/frontend/index.html b/dist/frontend/index.html new file mode 100644 index 0000000..9c6984a --- /dev/null +++ b/dist/frontend/index.html @@ -0,0 +1,67 @@ + + + + + + Your I-Ging Horoscope + + + +
+

Do you want to know the future?

+

☝️ Look into the future with your personal I-Ging Horoscope! ☝️

+

Click on the Button to receive your personal Horoscope. 100% accuracy guaranteed!

+ + +
+ + + + + + \ No newline at end of file diff --git a/start-local.sh b/start-local.sh index 1b20eb7..93cdbc5 100755 --- a/start-local.sh +++ b/start-local.sh @@ -22,8 +22,11 @@ npx tsc -p tsconfig.frontend.json mkdir -p dist/frontend cp frontend/index.html dist/frontend/ -# 4. Rename compiled frontend .js → .mjs -find dist/frontend -name "*.js" -exec bash -c 'mv "$0" "${0%.js}.mjs"' {} \; +mkdir -p dist/backend +cp backend/config.json dist/backend/ + +# 4. Rename compiled frontend event.js → event.mjs +find dist/frontend -name "event.js" -exec bash -c 'mv "$0" "${0%.js}.mjs"' {} \; # 5. Inject deploy mode echo "window.DEPLOY_MODE = 'local';" > dist/frontend/deploy.js