Skip to content

Commit

Permalink
extract attachment code to separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
targoninc-alex committed Jun 30, 2024
1 parent d211e0e commit 2cc0a4c
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 32 deletions.
24 changes: 2 additions & 22 deletions src/features/liveFeature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {UiChannel} from "../models/uiChannel";
import {ChannelProcessor} from "./messaging/channelProcessor";
import fs from "fs";
import {WritableAttachment} from "../models/writableAttachment";
import {AttachmentProcessor} from "./messaging/attachmentProcessor";

export class LiveFeature {
static enable(app: Application, userMap: Map<string, User>, db: MariaDbDatabase) {
Expand Down Expand Up @@ -174,28 +175,7 @@ export class LiveFeature {
}

CLI.debug(`Creating ${attachments.length} attachments`);
const fileFolder = process.env.FILE_FOLDER;
if (!fileFolder) {
client.send(JSON.stringify({error: "FILE_FOLDER is not set"}));
return;
}
if (!fs.existsSync(fileFolder)) {
fs.mkdirSync(fileFolder);
}
const messageFolder = fileFolder + "/" + message.id;
if (attachments.length > 0) {
fs.mkdirSync(messageFolder);
}
for (const attachment of attachments) {
if (attachment.data) {
await db.createAttachment(message.id, attachment.type, attachment.filename);
const attachmentPath = messageFolder + "/" + attachment.filename;
// @ts-ignore
const data = Buffer.from(attachment.data, "base64");
fs.writeFileSync(attachmentPath, data);
CLI.debug(`Created attachment with length ${attachment.data?.length} of type ${attachment.type} at ${attachmentPath}`);
}
}
await AttachmentProcessor.saveAttachments(db, message.id, attachments);
}

const sender = await db.getUserById(user.id);
Expand Down
58 changes: 58 additions & 0 deletions src/features/messaging/attachmentProcessor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import fs from "fs";
import {WritableAttachment} from "../../models/writableAttachment";
import {MariaDbDatabase} from "../database/mariaDbDatabase";
import {Attachment, Id} from "../database/models";
import {CLI} from "../../tooling/CLI";
import {Response} from "express";

export class AttachmentProcessor {
static ensureMessageFolder(messageId: Id) {
const fileFolder = process.env.FILE_FOLDER;
if (!fileFolder) {
throw new Error("FILE_FOLDER is not set");
}
if (!fs.existsSync(fileFolder)) {
fs.mkdirSync(fileFolder);
}
const messageFolder = fileFolder + "/" + messageId;
fs.mkdirSync(messageFolder);
}

static async saveAttachments(db: MariaDbDatabase, messageId: Id, attachments: WritableAttachment[]) {
if (!attachments || attachments.length === 0) {
return;
}

AttachmentProcessor.ensureMessageFolder(messageId);
const messageFolder = process.env.FILE_FOLDER + "/" + messageId;
for (const attachment of attachments) {
if (attachment.data) {
await this.saveAttachment(db, messageId, attachment, messageFolder);
}
}
}

static async saveAttachment(db: MariaDbDatabase, messageId: number, attachment: WritableAttachment, messageFolder: string) {
await db.createAttachment(messageId, attachment.type, attachment.filename);
const attachmentPath = messageFolder + "/" + attachment.filename;
// @ts-ignore
const data = Buffer.from(attachment.data, "base64");
fs.writeFileSync(attachmentPath, data);
CLI.debug(`Created attachment with length ${attachment.data?.length} of type ${attachment.type} at ${attachmentPath}`);
}

static async deleteMessage(messageId: number) {
const messageFolder = process.env.FILE_FOLDER + "/" + messageId;
if (fs.existsSync(messageFolder)) {
fs.rmSync(messageFolder, {recursive: true, force: true});
}
}

static pipeAttachment(res: Response, attachmentPath: string, messageAttachment: Attachment) {
const stat = fs.statSync(attachmentPath);
res.setHeader("Content-Type", messageAttachment?.type ?? "application/octet-stream");
res.setHeader("Content-Length", stat.size);
const stream = fs.createReadStream(attachmentPath);
stream.pipe(res);
}
}
7 changes: 2 additions & 5 deletions src/features/messaging/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {ReceivableMessage} from "../../models/receivableMessage";
import {UiChannel} from "../../models/uiChannel";
import {ChannelProcessor} from "./channelProcessor";
import fs from "fs";
import {AttachmentProcessor} from "./attachmentProcessor";

export class MessagingEndpoints {
static async checkChannelAccess(db: MariaDbDatabase, user: User, channelId: number) {
Expand Down Expand Up @@ -103,11 +104,7 @@ export class MessagingEndpoints {
return;
}
await db.deleteMessage(messageId);

const messageFolder = process.env.FILE_FOLDER + "/" + messageId;
if (fs.existsSync(messageFolder)) {
fs.rmSync(messageFolder, {recursive: true, force: true});
}
await AttachmentProcessor.deleteMessage(messageId);

CLI.success(`Message ${messageId} deleted by user ${user.id}.`);
res.json({message: "Message deleted"});
Expand Down
11 changes: 6 additions & 5 deletions src/features/messagingFeature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {MessagingEndpoints} from "./messaging/endpoints";
import fs from "fs";
import {CLI} from "../tooling/CLI";
import {User} from "./database/models";
import {AttachmentProcessor} from "./messaging/attachmentProcessor";

export class MessagingFeature {
static enable(app: Application, db: MariaDbDatabase) {
Expand Down Expand Up @@ -72,12 +73,12 @@ export class MessagingFeature {
}

CLI.debug(`Sending attachment ${attachmentPath}`);
const stat = fs.statSync(attachmentPath);
const messageAttachment = await db.getMessageAttachment(parseInt(messageId.toString()), filename.toString());
res.setHeader("Content-Type", messageAttachment?.type ?? "application/octet-stream");
res.setHeader("Content-Length", stat.size);
const stream = fs.createReadStream(attachmentPath);
stream.pipe(res);
if (!messageAttachment) {
res.status(404).send("Attachment not found");
return;
}
AttachmentProcessor.pipeAttachment(res, attachmentPath, messageAttachment);
});

return app;
Expand Down

0 comments on commit 2cc0a4c

Please sign in to comment.