Create initial project. Can launch and kill filmout_display.
This commit is contained in:
commit
08f825e809
|
@ -0,0 +1 @@
|
|||
node_modules
|
|
@ -0,0 +1,9 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.delay = void 0;
|
||||
function delay(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
exports.delay = delay;
|
||||
module.exports = { delay };
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/delay/index.ts"],"names":[],"mappings":";;;AAAA,SAAgB,KAAK,CAAE,EAAU;IAC7B,OAAO,IAAI,OAAO,CAAE,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAE,CAAC;AAC7D,CAAC;AAFD,sBAEC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC"}
|
|
@ -0,0 +1,24 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
require("dotenv/config");
|
||||
const log_1 = require("./log");
|
||||
const shell_1 = require("./shell");
|
||||
const delay_1 = require("./delay");
|
||||
let log = (0, log_1.createLog)('fm');
|
||||
let logfd = (0, log_1.createLog)('fd');
|
||||
log.info('Starting filmout_manager');
|
||||
function logfdstd(data) {
|
||||
logfd.info(data);
|
||||
}
|
||||
function logfdstderr(data) {
|
||||
logfd.error(data);
|
||||
}
|
||||
async function main() {
|
||||
let shell = new shell_1.Shell(['../filmout_display/build/bin/fd', '2560', '1600'], logfdstd, logfdstderr, null, true);
|
||||
shell.execute();
|
||||
await (0, delay_1.delay)(5000);
|
||||
shell.kill();
|
||||
process.exit();
|
||||
}
|
||||
main();
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,yBAAsB;AAgBtB,+BAAiC;AAEjC,mCAAgC;AAChC,mCAAgC;AAEhC,IAAI,GAAG,GAAY,IAAA,eAAS,EAAC,IAAI,CAAC,CAAC;AACnC,IAAI,KAAK,GAAY,IAAA,eAAS,EAAC,IAAI,CAAC,CAAC;AAErC,GAAG,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;AAErC,SAAS,QAAQ,CAAE,IAAU;IAC5B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClB,CAAC;AACD,SAAS,WAAW,CAAE,IAAU;IAC/B,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,IAAI;IAClB,IAAI,KAAK,GAAW,IAAI,aAAK,CAAC,CAAE,iCAAiC,EAAE,MAAM,EAAE,MAAM,CAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACxH,KAAK,CAAC,OAAO,EAAE,CAAC;IAChB,MAAM,IAAA,aAAK,EAAC,IAAI,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,EAAE,CAAC;IACb,OAAO,CAAC,IAAI,EAAE,CAAC;AAChB,CAAC;AAED,IAAI,EAAE,CAAA"}
|
|
@ -0,0 +1,50 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createLog = void 0;
|
||||
/** @module log */
|
||||
/** Wrapper for winston that tags streams and optionally writes files with a simple interface. */
|
||||
/** Module now also supports optional papertrail integration, other services to follow */
|
||||
const winston_1 = require("winston");
|
||||
const { SPLAT } = require('triple-beam');
|
||||
const { isObject } = require('lodash');
|
||||
const APP_NAME = process.env.APP_NAME || 'default';
|
||||
let winstonPapertrail;
|
||||
function formatObject(param) {
|
||||
if (isObject(param)) {
|
||||
return JSON.stringify(param);
|
||||
}
|
||||
return param;
|
||||
}
|
||||
const all = (0, winston_1.format)((info) => {
|
||||
const splat = info[SPLAT] || [];
|
||||
const message = formatObject(info.message);
|
||||
const rest = splat.map(formatObject).join(' ');
|
||||
info.message = `${message} ${rest}`;
|
||||
return info;
|
||||
});
|
||||
const myFormat = winston_1.format.printf(({ level, message, label, timestamp }) => {
|
||||
return `${timestamp} [${label}] ${level}: ${message}`;
|
||||
});
|
||||
/**
|
||||
* Returns a winston logger configured to service
|
||||
*
|
||||
* @param {string} label Label appearing on logger
|
||||
* @param {string} filename Optional file to write log to
|
||||
*
|
||||
* @returns {object} Winston logger
|
||||
*/
|
||||
function createLog(label, filename = null) {
|
||||
const tports = [new (winston_1.transports.Console)()];
|
||||
const fmat = winston_1.format.combine(all(), winston_1.format.label({ label }), winston_1.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss.SSS' }), winston_1.format.colorize(), myFormat);
|
||||
let papertrailOpts;
|
||||
if (filename !== null) {
|
||||
tports.push(new (winston_1.transports.File)({ filename }));
|
||||
}
|
||||
return (0, winston_1.createLogger)({
|
||||
format: fmat,
|
||||
transports: tports
|
||||
});
|
||||
}
|
||||
exports.createLog = createLog;
|
||||
module.exports = { createLog };
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/log/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;;;AAEZ,kBAAkB;AAClB,iGAAiG;AACjG,yFAAyF;AAEzF,qCAA2D;AAC3D,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;AACzC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvC,MAAM,QAAQ,GAAY,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,SAAS,CAAC;AAE5D,IAAI,iBAAiB,CAAC;AAEtB,SAAS,YAAY,CAAE,KAAW;IAChC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,GAAG,GAAG,IAAA,gBAAM,EAAC,CAAC,IAAU,EAAE,EAAE;IAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,CAAC,OAAO,GAAG,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC;IACpC,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,gBAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAQ,EAAE,EAAE;IAC5E,OAAO,GAAG,SAAS,KAAK,KAAK,KAAK,KAAK,KAAK,OAAO,EAAE,CAAC;AACxD,CAAC,CAAC,CAAC;AAEH;;;;;;;EAOE;AACF,SAAgB,SAAS,CAAE,KAAc,EAAE,WAAoB,IAAI;IAC/D,MAAM,MAAM,GAAW,CAAE,IAAI,CAAC,oBAAU,CAAC,OAAO,CAAC,EAAE,CAAE,CAAC;IACtD,MAAM,IAAI,GAAS,gBAAM,CAAC,OAAO,CAC7B,GAAG,EAAE,EACL,gBAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,EACvB,gBAAM,CAAC,SAAS,CAAC,EAAC,MAAM,EAAE,yBAAyB,EAAC,CAAC,EACrD,gBAAM,CAAC,QAAQ,EAAE,EACjB,QAAQ,CACX,CAAC;IACF,IAAI,cAAoB,CAAC;IAEzB,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,CAAC,IAAI,CAAE,IAAI,CAAC,oBAAU,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAE,CAAC;IACvD,CAAC;IAED,OAAO,IAAA,sBAAY,EAAC;QAChB,MAAM,EAAG,IAAI;QACb,UAAU,EAAG,MAAM;KACtB,CAAC,CAAC;AACP,CAAC;AAnBD,8BAmBC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,SAAS,EAAE,CAAC"}
|
|
@ -0,0 +1,48 @@
|
|||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.sendMail = void 0;
|
||||
const nodemailer_1 = __importDefault(require("nodemailer"));
|
||||
const log_1 = require("../log");
|
||||
const from = process.env['MAIL_FROM'];
|
||||
const smtp = process.env['MAIL_SMTP'];
|
||||
const port = typeof process.env['MAIL_SMTP_PORT'] !== 'undefined' ? 25 : parseInt(process.env['MAIL_SMTP_PORT'], 10);
|
||||
let transporter = null;
|
||||
const log = (0, log_1.createLog)('mail');
|
||||
if (typeof from !== 'undefined' && from !== null && from !== '' &&
|
||||
typeof smtp !== 'undefined' && smtp !== null && smtp !== '') {
|
||||
transporter = nodemailer_1.default.createTransport({
|
||||
host: smtp,
|
||||
port,
|
||||
secure: false,
|
||||
tls: { rejectUnauthorized: false }
|
||||
});
|
||||
}
|
||||
async function sendMail(to, subject, body) {
|
||||
if (transporter !== null) {
|
||||
try {
|
||||
await transporter.sendMail({
|
||||
from,
|
||||
to,
|
||||
subject,
|
||||
html: body
|
||||
});
|
||||
log.info(`Sent email "${subject}"`);
|
||||
}
|
||||
catch (err) {
|
||||
log.error(`Error sending email "${subject}"`);
|
||||
log.error(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn(`Email not configured, not sending "${subject}"`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
exports.sendMail = sendMail;
|
||||
module.exports = { sendMail };
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mail/index.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAoC;AACpC,gCAAmC;AAGnC,MAAM,IAAI,GAAY,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAC/C,MAAM,IAAI,GAAY,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAC/C,MAAM,IAAI,GAAY,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC,CAAC;AAE9H,IAAI,WAAW,GAA4B,IAAI,CAAC;AAEhD,MAAM,GAAG,GAAY,IAAA,eAAS,EAAC,MAAM,CAAC,CAAC;AAEvC,IAAI,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,EAAE;IAC3D,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;IAC9D,WAAW,GAAG,oBAAU,CAAC,eAAe,CAAC;QACrC,IAAI,EAAE,IAAI;QACV,IAAI;QACJ,MAAM,EAAG,KAAK;QACd,GAAG,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE;KACrC,CAAC,CAAC;AACP,CAAC;AAEM,KAAK,UAAU,QAAQ,CAAE,EAAW,EAAE,OAAgB,EAAE,IAAa;IACxE,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC;YACD,MAAM,WAAW,CAAC,QAAQ,CAAC;gBACvB,IAAI;gBACJ,EAAE;gBACF,OAAO;gBACP,IAAI,EAAE,IAAI;aACb,CAAC,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,eAAe,OAAO,GAAG,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,GAAG,CAAC,KAAK,CAAC,wBAAwB,OAAO,GAAG,CAAC,CAAC;YAC9C,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACf,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;SAAM,CAAC;QACJ,GAAG,CAAC,IAAI,CAAC,sCAAsC,OAAO,GAAG,CAAC,CAAC;QAC3D,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AApBD,4BAoBC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,QAAQ,EAAE,CAAC"}
|
|
@ -0,0 +1,66 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Shell = void 0;
|
||||
const child_process_1 = require("child_process");
|
||||
const log_1 = require("../log");
|
||||
const os_1 = require("os");
|
||||
class Shell {
|
||||
constructor(args, stdio = null, stderr = null, after = null, silent = false) {
|
||||
this.lines = [];
|
||||
this.stdio = null;
|
||||
this.stderr = null;
|
||||
this.after = null;
|
||||
this.silent = false;
|
||||
const bin = args.shift();
|
||||
this.bin = bin;
|
||||
this.args = args;
|
||||
this.stdio = stdio;
|
||||
this.stderr = stderr;
|
||||
this.silent = silent;
|
||||
this.after = after;
|
||||
this.log = (0, log_1.createLog)(bin);
|
||||
}
|
||||
async execute() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.child = (0, child_process_1.spawn)(this.bin, this.args);
|
||||
this.log.info(`Shell: ${this.bin} ${this.args.join(' ')}`);
|
||||
this.child.stdout.on('data', (data) => {
|
||||
if (!this.silent)
|
||||
this.log.info(data.toString());
|
||||
if (this.after !== null)
|
||||
this.lines.push(data);
|
||||
if (this.stdio !== null) {
|
||||
this.stdio(data.toString());
|
||||
}
|
||||
});
|
||||
this.child.stderr.on('data', (data) => {
|
||||
if (!this.silent)
|
||||
this.log.warn(data.toString());
|
||||
if (this.stderr !== null) {
|
||||
this.stderr(data.toString());
|
||||
}
|
||||
});
|
||||
this.child.on('close', (code) => {
|
||||
if (this.after !== null) {
|
||||
this.after(this.lines.join(os_1.EOL));
|
||||
}
|
||||
if (code === 0) {
|
||||
this.log.info(`Complete: ${this.bin} ${this.args.join(' ')}`);
|
||||
return resolve(code);
|
||||
}
|
||||
else {
|
||||
this.log.error(`Error executing: ${this.bin} ${this.args.join(' ')}`);
|
||||
return reject(code);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
kill() {
|
||||
this.log.warn(`Killing: ${this.bin} ${this.args.join(' ')}`);
|
||||
//this.child.stdin.pause();
|
||||
this.child.kill();
|
||||
}
|
||||
}
|
||||
exports.Shell = Shell;
|
||||
module.exports = { Shell };
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/shell/index.ts"],"names":[],"mappings":"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"}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "filmout_manager",
|
||||
"version": "0.0.1",
|
||||
"description": "Filmout manager is the control software for creating filmouts with the Galil and filmout display.",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"compile": "./node_modules/.bin/tsc -p tsconfig.json"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/multer": "^1.4.11",
|
||||
"@types/node": "^20.12.7",
|
||||
"@types/nodemailer": "^6.4.14",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@types/ws": "^8.5.10",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"body-parser": "^1.20.2",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.19.2",
|
||||
"galil": "github:artaic/galil",
|
||||
"handlebars": "^4.7.8",
|
||||
"lodash": "^4.17.21",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"nodemailer": "^6.9.13",
|
||||
"sqlite3": "^5.1.7",
|
||||
"triple-beam": "^1.4.1",
|
||||
"uuid": "^9.0.1",
|
||||
"winston": "^3.13.0",
|
||||
"ws": "^8.16.0"
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
export function delay (ms: number) {
|
||||
return new Promise( resolve => setTimeout(resolve, ms) );
|
||||
}
|
||||
|
||||
module.exports = { delay };
|
|
@ -0,0 +1,42 @@
|
|||
import 'dotenv/config'
|
||||
import express from 'express';
|
||||
import { Express, Request, Response, NextFunction } from 'express'
|
||||
import fs from 'fs/promises';
|
||||
import { createReadStream } from 'fs';
|
||||
import { tmpdir } from 'os';
|
||||
import { join } from 'path';
|
||||
import { createHash, Hash } from 'crypto';
|
||||
import { Database } from 'sqlite3';
|
||||
import bodyParser from 'body-parser';
|
||||
import multer from 'multer';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import getType from 'mime';
|
||||
import type { Logger } from 'winston';
|
||||
import * as Handlebars from 'handlebars';
|
||||
|
||||
import { createLog } from './log'
|
||||
import { sendMail } from './mail';
|
||||
import { Shell } from './shell';
|
||||
import { delay } from './delay';
|
||||
|
||||
let log : Logger = createLog('fm');
|
||||
let logfd : Logger = createLog('fd');
|
||||
|
||||
log.info('Starting filmout_manager');
|
||||
|
||||
function logfdstd (data : any) {
|
||||
logfd.info(data);
|
||||
}
|
||||
function logfdstderr (data : any) {
|
||||
logfd.error(data);
|
||||
}
|
||||
|
||||
async function main () {
|
||||
let shell : Shell = new Shell([ '../filmout_display/build/bin/fd', '2560', '1600' ], logfdstd, logfdstderr, null, true);
|
||||
shell.execute();
|
||||
await delay(5000);
|
||||
shell.kill();
|
||||
process.exit();
|
||||
}
|
||||
|
||||
main()
|
|
@ -0,0 +1,63 @@
|
|||
'use strict'
|
||||
|
||||
/** @module log */
|
||||
/** Wrapper for winston that tags streams and optionally writes files with a simple interface. */
|
||||
/** Module now also supports optional papertrail integration, other services to follow */
|
||||
|
||||
import { format, transports, createLogger } from 'winston';
|
||||
const { SPLAT } = require('triple-beam');
|
||||
const { isObject } = require('lodash');
|
||||
|
||||
const APP_NAME : string = process.env.APP_NAME || 'default';
|
||||
|
||||
let winstonPapertrail;
|
||||
|
||||
function formatObject (param : any) {
|
||||
if (isObject(param)) {
|
||||
return JSON.stringify(param);
|
||||
}
|
||||
return param;
|
||||
}
|
||||
|
||||
const all = format((info : any) => {
|
||||
const splat = info[SPLAT] || [];
|
||||
const message = formatObject(info.message);
|
||||
const rest = splat.map(formatObject).join(' ');
|
||||
info.message = `${message} ${rest}`;
|
||||
return info;
|
||||
});
|
||||
|
||||
const myFormat = format.printf(({ level, message, label, timestamp } : any) => {
|
||||
return `${timestamp} [${label}] ${level}: ${message}`;
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns a winston logger configured to service
|
||||
*
|
||||
* @param {string} label Label appearing on logger
|
||||
* @param {string} filename Optional file to write log to
|
||||
*
|
||||
* @returns {object} Winston logger
|
||||
*/
|
||||
export function createLog (label : string, filename : string = null) {
|
||||
const tports : any[] = [ new (transports.Console)() ];
|
||||
const fmat : any = format.combine(
|
||||
all(),
|
||||
format.label({ label }),
|
||||
format.timestamp({format: 'YYYY-MM-DD HH:mm:ss.SSS'}),
|
||||
format.colorize(),
|
||||
myFormat,
|
||||
);
|
||||
let papertrailOpts : any;
|
||||
|
||||
if (filename !== null) {
|
||||
tports.push( new (transports.File)({ filename }) );
|
||||
}
|
||||
|
||||
return createLogger({
|
||||
format : fmat,
|
||||
transports : tports
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { createLog };
|
|
@ -0,0 +1,45 @@
|
|||
import nodemailer from 'nodemailer';
|
||||
import { createLog } from '../log';
|
||||
import type { Logger } from 'winston';
|
||||
|
||||
const from : string = process.env['MAIL_FROM'];
|
||||
const smtp : string = process.env['MAIL_SMTP'];
|
||||
const port : number = typeof process.env['MAIL_SMTP_PORT'] !== 'undefined' ? 25 : parseInt(process.env['MAIL_SMTP_PORT'], 10);
|
||||
|
||||
let transporter : nodemailer.Transporter = null;
|
||||
|
||||
const log : Logger = createLog('mail');
|
||||
|
||||
if (typeof from !== 'undefined' && from !== null && from !== '' &&
|
||||
typeof smtp !== 'undefined' && smtp !== null && smtp !== '') {
|
||||
transporter = nodemailer.createTransport({
|
||||
host: smtp,
|
||||
port,
|
||||
secure : false,
|
||||
tls: { rejectUnauthorized: false }
|
||||
});
|
||||
}
|
||||
|
||||
export async function sendMail (to : string, subject : string, body : string) : Promise<boolean>{
|
||||
if (transporter !== null) {
|
||||
try {
|
||||
await transporter.sendMail({
|
||||
from,
|
||||
to,
|
||||
subject,
|
||||
html: body
|
||||
});
|
||||
log.info(`Sent email "${subject}"`);
|
||||
} catch (err) {
|
||||
log.error(`Error sending email "${subject}"`);
|
||||
log.error(err);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
log.warn(`Email not configured, not sending "${subject}"`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = { sendMail };
|
|
@ -0,0 +1,71 @@
|
|||
import { spawn, ChildProcessWithoutNullStreams } from 'child_process';
|
||||
import { createLog } from '../log';
|
||||
import type { Logger } from 'winston';
|
||||
import { EOL } from 'os';
|
||||
|
||||
export class Shell {
|
||||
private child : ChildProcessWithoutNullStreams;
|
||||
private log : Logger;
|
||||
private bin : string;
|
||||
private args : any[];
|
||||
private lines : string[] = [];
|
||||
private stdio : Function = null;
|
||||
private stderr : Function = null;
|
||||
private after : Function = null;
|
||||
private silent : boolean = false;
|
||||
|
||||
constructor (args : any[], stdio : Function = null, stderr : Function = null, after : Function = null, silent : boolean = false) {
|
||||
const bin : string = args.shift();
|
||||
this.bin = bin;
|
||||
this.args = args;
|
||||
this.stdio = stdio;
|
||||
this.stderr = stderr;
|
||||
this.silent = silent;
|
||||
this.after = after;
|
||||
this.log = createLog(bin);
|
||||
}
|
||||
|
||||
public async execute () : Promise<number> {
|
||||
return new Promise((resolve : Function, reject : Function) => {
|
||||
this.child = spawn(this.bin, this.args);
|
||||
|
||||
this.log.info(`Shell: ${this.bin} ${this.args.join(' ')}`);
|
||||
|
||||
this.child.stdout.on('data', (data : string) => {
|
||||
if (!this.silent) this.log.info(data.toString());
|
||||
if (this.after !== null) this.lines.push(data);
|
||||
if (this.stdio !== null) {
|
||||
this.stdio(data.toString());
|
||||
}
|
||||
});
|
||||
|
||||
this.child.stderr.on('data', (data : string) => {
|
||||
if (!this.silent) this.log.warn(data.toString());
|
||||
if (this.stderr !== null) {
|
||||
this.stderr(data.toString());
|
||||
}
|
||||
});
|
||||
|
||||
this.child.on('close', (code : number) => {
|
||||
if (this.after !== null) {
|
||||
this.after(this.lines.join(EOL));
|
||||
}
|
||||
if (code === 0) {
|
||||
this.log.info(`Complete: ${this.bin} ${this.args.join(' ')}`);
|
||||
return resolve(code);
|
||||
} else {
|
||||
this.log.error(`Error executing: ${this.bin} ${this.args.join(' ')}`);
|
||||
return reject(code);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public kill () {
|
||||
this.log.warn(`Killing: ${this.bin} ${this.args.join(' ')}`);
|
||||
//this.child.stdin.pause();
|
||||
this.child.kill();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { Shell };
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true,
|
||||
"target": "ES2020",
|
||||
"noImplicitAny": true,
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"removeComments" : false,
|
||||
"baseUrl" : "dist",
|
||||
"outDir": "./dist/",
|
||||
"rootDir" : "./src/",
|
||||
"paths" : {
|
||||
}
|
||||
},
|
||||
"exclude" : [
|
||||
"./dist"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue