iching-broker-level2/dist/backend/broker.js

138 lines
5.5 KiB
JavaScript
Raw Normal View History

2025-04-17 12:46:32 +00:00
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" <the.oracle@holy.mountain>',
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 = "<h1>" + line + "</h1>";
}
else if (line.startsWith("Judgement")) {
const judgement = { type: "Judgement" };
currentNode.child = judgement;
currentNode = judgement;
currentNode.value = "<h3>" + line + "</h3>";
}
else if (line.startsWith("Images")) {
const images = { type: "Images" };
currentNode.child = images;
currentNode = images;
currentNode.value = "<h3>" + line + "</h3>";
}
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 + "<br>";
}
}
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("<h1>", "<div style=\"border: 1px dotted gray; border-radius: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px; padding-bottom: 10px; width: auto; display: inline-block; box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.2);\"><h1>");
node.value = node.value?.replace("</h1>", "</h1><div style=\"border: 1px solid gray; border-radius: 25px; padding-left: 30px; padding-right: 30px; padding-top: 20px; width: auto; display: inline-block; text-align: center; box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.2);\"><h2>");
node.value = node.value?.replace("<br>", " - ");
outputHTML = "<br><p>" + node.value + "</h2></div></p>";
outputHTML = outputHTML + render(node.child);
return outputHTML;
case "Images":
outputHTML = "<p>" + node.value + "</p></div>"; //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 = "<br><br><p><div style=\"padding-left: 20px; padding-right: 20px; padding-top: 20px; display: inline-block; color: gray; text-align: center;\">" + node.value + "</div></p><br>";
outputHTML = outputHTML + render(node.child);
return outputHTML;
default:
outputHTML = "<p>" + node.value + "</p>";
outputHTML = outputHTML + render(node.child);
return outputHTML;
}
}