Skip to content

Commit

Permalink
Prettier format
Browse files Browse the repository at this point in the history
  • Loading branch information
miku448 committed Aug 10, 2024
1 parent 0a942df commit d2d2197
Show file tree
Hide file tree
Showing 205 changed files with 6,277 additions and 8,568 deletions.
12 changes: 6 additions & 6 deletions apps/bot-directory/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import path from 'path';
import fs from 'fs';

const DB_PATH = path.join(__dirname, "../db")
const DB_PATH = path.join(__dirname, '../db');
const config = {
"DB_PATH": DB_PATH,
"ASSET_PATH": `${DB_PATH}/assets`,
"BOT_PATH": `${DB_PATH}/bots`,
}
DB_PATH: DB_PATH,
ASSET_PATH: `${DB_PATH}/assets`,
BOT_PATH: `${DB_PATH}/bots`,
};

fs.mkdir(config.BOT_PATH, { recursive: true }, (err) => {
if (err) throw err;
Expand All @@ -15,4 +15,4 @@ fs.mkdir(config.ASSET_PATH, { recursive: true }, (err) => {
if (err) throw err;
});

export default config;
export default config;
34 changes: 15 additions & 19 deletions apps/bot-directory/src/paths/addBot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { readFileSync } from "fs";
import { Request, Response } from "express";
import { readFileSync } from 'fs';
import { Request, Response } from 'express';
import {
BUCKET,
MikuCard,
Expand All @@ -8,17 +8,16 @@ import {
importAndReplaceNovelStateAssets,
inputToNovelState,
tavernCardToNovelState,
} from "@mikugg/bot-utils";
import { uploadAssetHandler, uploadS3File } from "../s3server";
} from '@mikugg/bot-utils';
import { uploadAssetHandler, uploadS3File } from '../s3server';
// Registers a bot configuration
export default async function addBot(req: Request, res: Response) {
try {
if (!req.file?.path) throw "file not found";
if (!req.file?.originalname.endsWith(".json"))
throw "Invalid file type, only .json is supported";
if (!req.file?.path) throw 'file not found';
if (!req.file?.originalname.endsWith('.json')) throw 'Invalid file type, only .json is supported';

const buffer = readFileSync(req.file.path);
const mikuCard = JSON.parse(buffer.toString("utf-8")) as MikuCard;
const mikuCard = JSON.parse(buffer.toString('utf-8')) as MikuCard;

const novelState = inputToNovelState(mikuCard);
const novel = await importAndReplaceNovelStateAssets(novelState.novel, {
Expand All @@ -29,19 +28,16 @@ export default async function addBot(req: Request, res: Response) {
console.log(`Uploading ${progress}/${total}... ${bytes} bytes`);
},
uploadAsset: async (assetBase64URI) => {
if (assetBase64URI.startsWith("data:")) {
if (assetBase64URI.startsWith('data:')) {
const hash = await hashBase64URI(assetBase64URI);
// convert base64 to file
const buffer = Buffer.from(
assetBase64URI.split("base64,")[1],
"base64"
);
const buffer = Buffer.from(assetBase64URI.split('base64,')[1], 'base64');
await uploadS3File(BUCKET.ASSETS, hash, buffer);
const fileName = await uploadAssetHandler(
{
body: {
fileName: hash,
contentType: assetBase64URI.split("data:")[1].split(";")[0],
contentType: assetBase64URI.split('data:')[1].split(';')[0],
},
} as any,
{
Expand All @@ -51,7 +47,7 @@ export default async function addBot(req: Request, res: Response) {
send: () => {},
};
},
} as any
} as any,
);
return { success: true, assetId: fileName };
} else {
Expand All @@ -62,13 +58,13 @@ export default async function addBot(req: Request, res: Response) {
});
const cardJSON = JSON.stringify({
novel,
version: "v3",
version: 'v3',
});
const cardJSONBuffer = Buffer.from(cardJSON, "utf-8");
const cardJSONBuffer = Buffer.from(cardJSON, 'utf-8');
const hash = await hashBase64(cardJSON);
await uploadS3File(BUCKET.BOTS, hash + ".json", cardJSONBuffer);
await uploadS3File(BUCKET.BOTS, hash + '.json', cardJSONBuffer);

res.redirect("/");
res.redirect('/');
res.end();
} catch (err) {
res.status(400).send(`
Expand Down
33 changes: 14 additions & 19 deletions apps/bot-directory/src/paths/deleteBot.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
import fs from "fs";
import { Request, Response } from "express";
import { MikuCard, NovelV3, extractNovelAssets } from "@mikugg/bot-utils";
import config from "../config";
import fs from 'fs';
import { Request, Response } from 'express';
import { MikuCard, NovelV3, extractNovelAssets } from '@mikugg/bot-utils';
import config from '../config';

export default async function deletBot(req: Request, res: Response) {
try {
const hash = req.params?.hash || "";
const _botRaw = fs.readFileSync(`${config.BOT_PATH}/${hash}`, "utf8");
const hash = req.params?.hash || '';
const _botRaw = fs.readFileSync(`${config.BOT_PATH}/${hash}`, 'utf8');
const _bot = JSON.parse(_botRaw) as {
version: "v3";
version: 'v3';
novel: NovelV3.NovelState;
};

try {
const deleteAsset = async (asset: string) => {
if (fs.existsSync(`${config.ASSET_PATH}/${asset}`))
fs.unlinkSync(`${config.ASSET_PATH}/${asset}`);
if (fs.existsSync(`${config.ASSET_PATH}/480p_${asset}`))
fs.unlinkSync(`${config.ASSET_PATH}/480p_${asset}`);
if (fs.existsSync(`${config.ASSET_PATH}/720p_${asset}`))
fs.unlinkSync(`${config.ASSET_PATH}/720p_${asset}`);
if (fs.existsSync(`${config.ASSET_PATH}/1080p_${asset}`))
fs.unlinkSync(`${config.ASSET_PATH}/1080p_${asset}`);
if (fs.existsSync(`${config.ASSET_PATH}/4k_${asset}`))
fs.unlinkSync(`${config.ASSET_PATH}/4k_${asset}`);
if (fs.existsSync(`${config.ASSET_PATH}/${asset}`)) fs.unlinkSync(`${config.ASSET_PATH}/${asset}`);
if (fs.existsSync(`${config.ASSET_PATH}/480p_${asset}`)) fs.unlinkSync(`${config.ASSET_PATH}/480p_${asset}`);
if (fs.existsSync(`${config.ASSET_PATH}/720p_${asset}`)) fs.unlinkSync(`${config.ASSET_PATH}/720p_${asset}`);
if (fs.existsSync(`${config.ASSET_PATH}/1080p_${asset}`)) fs.unlinkSync(`${config.ASSET_PATH}/1080p_${asset}`);
if (fs.existsSync(`${config.ASSET_PATH}/4k_${asset}`)) fs.unlinkSync(`${config.ASSET_PATH}/4k_${asset}`);
};
const {
assets: { images, videos },
Expand All @@ -35,12 +30,12 @@ export default async function deletBot(req: Request, res: Response) {
await deleteAsset(video[0]);
}
} catch (err) {
console.error("delete asset error", err);
console.error('delete asset error', err);
}

fs.unlinkSync(`${config.BOT_PATH}/${hash}`);

res.redirect("/");
res.redirect('/');
res.end();
} catch (err) {
res.status(400).send(err);
Expand Down
110 changes: 48 additions & 62 deletions apps/bot-directory/src/s3server.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,28 @@
import fs from "fs";
import path from "path";
import multer from "multer";
import express, { Express, Request, Response } from "express";
import { BUCKET, hashBase64 } from "@mikugg/bot-utils";
import sharp from "sharp";
export { BUCKET } from "@mikugg/bot-utils";
import fs from 'fs';
import path from 'path';
import multer from 'multer';
import express, { Express, Request, Response } from 'express';
import { BUCKET, hashBase64 } from '@mikugg/bot-utils';
import sharp from 'sharp';
export { BUCKET } from '@mikugg/bot-utils';

const randomString = (length: number = 10) => {
let result = "";
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
};

const dataDir = path.join(__dirname, "../db"); // Directory to store files
const dataDir = path.join(__dirname, '../db'); // Directory to store files

if (!fs.existsSync(dataDir)) {
fs.mkdirSync(dataDir, { recursive: true });
}

export function uploadS3File(
bucket: BUCKET,
key: string,
content: Buffer
): Promise<void> {
export function uploadS3File(bucket: BUCKET, key: string, content: Buffer): Promise<void> {
const filePath = path.join(dataDir, `${bucket}/${key}`);
return new Promise((resolve, reject) => {
fs.writeFile(filePath, content, (err) => {
Expand All @@ -50,61 +45,55 @@ export function getS3File(bucket: BUCKET, key: string): Buffer | null {

const upload = multer({ storage: multer.memoryStorage() });

export const uploadAssetHandler = async (
req: Request,
res: Response
): Promise<string> => {
export const uploadAssetHandler = async (req: Request, res: Response): Promise<string> => {
const _fileName = String(req.body.fileName);
try {
const contentType = String(req.body.contentType);
if (!_fileName || !contentType) {
res.status(400).send("No fileName or contentType.");
return "";
res.status(400).send('No fileName or contentType.');
return '';
}
// read file as buffer
const filePath = path.join(path.join(dataDir, `assets/${_fileName}`));
const fileBuffer = fs.readFileSync(filePath);
const fileHash = await hashBase64(fileBuffer.toString("base64"));
const fileName = `${fileHash}.${contentType.split("/")[1]}`;
const fileHash = await hashBase64(fileBuffer.toString('base64'));
const fileName = `${fileHash}.${contentType.split('/')[1]}`;

// change _fileName to fileName
fs.renameSync(filePath, path.join(dataDir, `assets/${fileName}`));
// Check if the file is an image
if (contentType.startsWith("image/")) {
if (contentType.startsWith('image/')) {
let resizedImage;

if (contentType === "image/gif") {
if (contentType === 'image/gif') {
// Handling GIFs: Sharp doesn't support GIF resizing, so we just skip resizing for GIFs
resizedImage = fileBuffer;
} else {
// Resize other image types
resizedImage = await sharp(fileBuffer)
.resize({ height: 480, fit: "inside", withoutEnlargement: true })
.resize({ height: 480, fit: 'inside', withoutEnlargement: true })
// @ts-ignore
.toFormat(contentType.split("/")[1], { quality: 70 }) // Adjust quality for supported formats
.toFormat(contentType.split('/')[1], { quality: 70 }) // Adjust quality for supported formats
.toBuffer();
}

// Upload the resized image
const resizedFileName = `480p_${fileName}`;
fs.writeFileSync(
path.join(dataDir, `assets/${resizedFileName}`),
resizedImage
);
fs.writeFileSync(path.join(dataDir, `assets/${resizedFileName}`), resizedImage);
}
res.send({
fileName: fileName,
fileSize: fileBuffer.length,
});
return fileName;
} catch (err) {
console.warn("Error resizing image:", _fileName);
console.warn('Error resizing image:', _fileName);
console.error(err);
res.send({
fileName: _fileName,
fileSize: 0,
});
return "";
return '';
}

// check file extension
Expand All @@ -113,44 +102,44 @@ export const uploadAssetHandler = async (
export default function s3ServerDecorator(app: Express): void {
// for each bucket
for (const bucket of Object.values(BUCKET)) {
app.put(`/s3/${bucket}/:key`, upload.single("file"), async (req, res) => {
app.put(`/s3/${bucket}/:key`, upload.single('file'), async (req, res) => {
if (!req.file) {
return res.status(400).send("No file uploaded.");
return res.status(400).send('No file uploaded.');
}
await uploadS3File(bucket, req.params.key, req.file.buffer);
res.status(200).send("File uploaded successfully.");
res.status(200).send('File uploaded successfully.');
});

app.get(`/s3/${bucket}/:key`, (req, res) => {
const file = getS3File(bucket, req.params.key);
if (file) {
if (req.params.key.endsWith(".webm")) res.contentType("video/webm");
if (req.params.key.endsWith(".mp4")) res.contentType("video/mp4");
if (req.params.key.endsWith(".png")) res.contentType("image/png");
if (req.params.key.endsWith(".jpg")) res.contentType("image/jpeg");
if (req.params.key.endsWith(".jpeg")) res.contentType("image/jpeg");
if (req.params.key.endsWith(".gif")) res.contentType("image/gif");
if (req.params.key.endsWith(".mp3")) res.contentType("audio/mpeg");
if (req.params.key.endsWith(".mpeg")) res.contentType("audio/mpeg");
if (req.params.key.endsWith(".wav")) res.contentType("audio/wav");
if (req.params.key.endsWith(".ogg")) res.contentType("audio/ogg");
if (req.params.key.endsWith('.webm')) res.contentType('video/webm');
if (req.params.key.endsWith('.mp4')) res.contentType('video/mp4');
if (req.params.key.endsWith('.png')) res.contentType('image/png');
if (req.params.key.endsWith('.jpg')) res.contentType('image/jpeg');
if (req.params.key.endsWith('.jpeg')) res.contentType('image/jpeg');
if (req.params.key.endsWith('.gif')) res.contentType('image/gif');
if (req.params.key.endsWith('.mp3')) res.contentType('audio/mpeg');
if (req.params.key.endsWith('.mpeg')) res.contentType('audio/mpeg');
if (req.params.key.endsWith('.wav')) res.contentType('audio/wav');
if (req.params.key.endsWith('.ogg')) res.contentType('audio/ogg');
res.send(file);
} else {
res.status(404).send("File not found.");
res.status(404).send('File not found.');
}
});
}

app.get("/asset-upload/ask", (req, res) => {
app.get('/asset-upload/ask', (req, res) => {
// check contentType query param
const contentType = String(req.query.contentType);
if (!contentType) {
return res.status(400).send("No contentType query param.");
return res.status(400).send('No contentType query param.');
}
// check file extension
const ext = contentType.split("/")[1];
const ext = contentType.split('/')[1];
if (!ext) {
return res.status(400).send("Invalid contentType.");
return res.status(400).send('Invalid contentType.');
}
const fileName = `_temp_${Date.now()}_${randomString()}.${ext}`;

Expand All @@ -160,28 +149,25 @@ export default function s3ServerDecorator(app: Express): void {
});
});

app.use(
"/asset-upload/presigned/:fileName",
express.raw({ type: "application/octet-stream", limit: "50mb" })
);
app.use('/asset-upload/presigned/:fileName', express.raw({ type: 'application/octet-stream', limit: '50mb' }));

app.put("/asset-upload/presigned/:fileName", (req, res) => {
app.put('/asset-upload/presigned/:fileName', (req, res) => {
const fileName = req.params.fileName;
if (!fileName) {
return res.status(400).send("No fileName in path.");
return res.status(400).send('No fileName in path.');
}

const filePath = path.join(path.join(dataDir, `assets/${fileName}`));

// Now `req.body` should be a Buffer
fs.writeFile(filePath, req.body, (err) => {
if (err) {
console.error("Error writing file:", err);
return res.status(500).send("Error writing file.");
console.error('Error writing file:', err);
return res.status(500).send('Error writing file.');
}
res.status(200).send("File uploaded successfully.");
res.status(200).send('File uploaded successfully.');
});
});

app.post("/asset-upload/complete", uploadAssetHandler);
app.post('/asset-upload/complete', uploadAssetHandler);
}
Loading

0 comments on commit d2d2197

Please sign in to comment.