aboutsummaryrefslogtreecommitdiff
path: root/src/server/ActionUtilities.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/ActionUtilities.ts')
-rw-r--r--src/server/ActionUtilities.ts123
1 files changed, 102 insertions, 21 deletions
diff --git a/src/server/ActionUtilities.ts b/src/server/ActionUtilities.ts
index 4fe7374d1..60f66c878 100644
--- a/src/server/ActionUtilities.ts
+++ b/src/server/ActionUtilities.ts
@@ -1,46 +1,81 @@
-import * as fs from 'fs';
+import { readFile, writeFile, exists, mkdir, unlink, createWriteStream } from 'fs';
import { ExecOptions } from 'shelljs';
import { exec } from 'child_process';
import * as path from 'path';
import * as rimraf from "rimraf";
-import { yellow } from 'colors';
+import { yellow, Color } from 'colors';
+import * as nodemailer from "nodemailer";
+import { MailOptions } from "nodemailer/lib/json-transport";
+import Mail = require('nodemailer/lib/mailer');
+
+const projectRoot = path.resolve(__dirname, "../../");
+export function pathFromRoot(relative?: string) {
+ if (!relative) {
+ return projectRoot;
+ }
+ return path.resolve(projectRoot, relative);
+}
+
+export async function fileDescriptorFromStream(path: string) {
+ const logStream = createWriteStream(path);
+ return new Promise<number>(resolve => logStream.on("open", resolve));
+}
export const command_line = (command: string, fromDirectory?: string) => {
return new Promise<string>((resolve, reject) => {
const options: ExecOptions = {};
if (fromDirectory) {
- options.cwd = path.join(__dirname, fromDirectory);
+ options.cwd = fromDirectory ? path.resolve(projectRoot, fromDirectory) : projectRoot;
}
exec(command, options, (err, stdout) => err ? reject(err) : resolve(stdout));
});
};
export const read_text_file = (relativePath: string) => {
- const target = path.join(__dirname, relativePath);
+ const target = path.resolve(__dirname, relativePath);
return new Promise<string>((resolve, reject) => {
- fs.readFile(target, (err, data) => err ? reject(err) : resolve(data.toString()));
+ readFile(target, (err, data) => err ? reject(err) : resolve(data.toString()));
});
};
export const write_text_file = (relativePath: string, contents: any) => {
- const target = path.join(__dirname, relativePath);
+ const target = path.resolve(__dirname, relativePath);
return new Promise<void>((resolve, reject) => {
- fs.writeFile(target, contents, (err) => err ? reject(err) : resolve());
+ writeFile(target, contents, (err) => err ? reject(err) : resolve());
});
};
-export interface LogData {
+export type Messager<T> = (outcome: { result: T | undefined, error: Error | null }) => string;
+
+export interface LogData<T> {
startMessage: string;
- endMessage: string;
- action: () => void | Promise<void>;
+ // if you care about the execution informing your log, you can pass in a function that takes in the result and a potential error and decides what to write
+ endMessage: string | Messager<T>;
+ action: () => T | Promise<T>;
+ color?: Color;
}
let current = Math.ceil(Math.random() * 20);
-export async function log_execution({ startMessage, endMessage, action }: LogData) {
- const color = `\x1b[${31 + current++ % 6}m%s\x1b[0m`;
- console.log(color, `${startMessage}...`);
- await action();
- console.log(color, endMessage);
+export async function log_execution<T>({ startMessage, endMessage, action, color }: LogData<T>): Promise<T | undefined> {
+ let result: T | undefined = undefined, error: Error | null = null;
+ const resolvedColor = color || `\x1b[${31 + ++current % 6}m%s\x1b[0m`;
+ log_helper(`${startMessage}...`, resolvedColor);
+ try {
+ result = await action();
+ } catch (e) {
+ error = e;
+ } finally {
+ log_helper(typeof endMessage === "string" ? endMessage : endMessage({ result, error }), resolvedColor);
+ }
+ return result;
+}
+
+function log_helper(content: string, color: Color | string) {
+ if (typeof color === "string") {
+ console.log(color, content);
+ } else {
+ console.log(color(content));
+ }
}
export function logPort(listener: string, port: number) {
@@ -61,10 +96,10 @@ export function msToTime(duration: number) {
}
export const createIfNotExists = async (path: string) => {
- if (await new Promise<boolean>(resolve => fs.exists(path, resolve))) {
+ if (await new Promise<boolean>(resolve => exists(path, resolve))) {
return true;
}
- return new Promise<boolean>(resolve => fs.mkdir(path, error => resolve(error === null)));
+ return new Promise<boolean>(resolve => mkdir(path, error => resolve(error === null)));
};
export async function Prune(rootDirectory: string): Promise<boolean> {
@@ -72,8 +107,54 @@ export async function Prune(rootDirectory: string): Promise<boolean> {
return error === null;
}
-export const Destroy = (mediaPath: string) => new Promise<boolean>(resolve => fs.unlink(mediaPath, error => resolve(error === null)));
+export const Destroy = (mediaPath: string) => new Promise<boolean>(resolve => unlink(mediaPath, error => resolve(error === null)));
-export function addBeforeExitHandler(handler: NodeJS.BeforeExitListener) {
- process.on("beforeExit", handler);
-}
+export namespace Email {
+
+ const smtpTransport = nodemailer.createTransport({
+ service: 'Gmail',
+ auth: {
+ user: 'brownptcdash@gmail.com',
+ pass: 'browngfx1'
+ }
+ });
+
+ export interface DispatchOptions<T extends string | string[]> {
+ to: T;
+ subject: string;
+ content: string;
+ attachments?: Mail.Attachment | Mail.Attachment[];
+ }
+
+ export interface DispatchFailure {
+ recipient: string;
+ error: Error;
+ }
+
+ export async function dispatchAll({ to, subject, content, attachments }: DispatchOptions<string[]>) {
+ const failures: DispatchFailure[] = [];
+ await Promise.all(to.map(async recipient => {
+ let error: Error | null;
+ const resolved = attachments ? "length" in attachments ? attachments : [attachments] : undefined;
+ if ((error = await Email.dispatch({ to: recipient, subject, content, attachments: resolved })) !== null) {
+ failures.push({
+ recipient,
+ error
+ });
+ }
+ }));
+ return failures.length ? failures : undefined;
+ }
+
+ export async function dispatch({ to, subject, content, attachments }: DispatchOptions<string>): Promise<Error | null> {
+ const mailOptions = {
+ to,
+ from: 'brownptcdash@gmail.com',
+ subject,
+ text: `Hello ${to.split("@")[0]},\n\n${content}`,
+ attachments
+ } as MailOptions;
+ return new Promise<Error | null>(resolve => smtpTransport.sendMail(mailOptions, resolve));
+ }
+
+} \ No newline at end of file