From 759d60a704168b91fc7722dd45e560457237d222 Mon Sep 17 00:00:00 2001 From: Alexander Alemayhu Date: Fri, 24 Nov 2023 21:01:34 +0100 Subject: [PATCH] feat: add endpoints for retrieving only upload info --- src/controllers/SimpleUploadController.ts | 86 +++++++++++++++++++ src/controllers/UploadController.ts | 3 +- src/routes/SimpleUploadRouter.ts | 17 ++++ src/server.ts | 2 + src/services/UploadService.ts | 8 +- .../uploads/GeneratePackagesUseCase.ts | 2 - 6 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 src/controllers/SimpleUploadController.ts create mode 100644 src/routes/SimpleUploadRouter.ts diff --git a/src/controllers/SimpleUploadController.ts b/src/controllers/SimpleUploadController.ts new file mode 100644 index 000000000..03cca2dcb --- /dev/null +++ b/src/controllers/SimpleUploadController.ts @@ -0,0 +1,86 @@ +import fs from 'fs'; +import path from 'path'; + +import express from 'express'; +import multer from 'multer'; + +import { sendError } from '../lib/error/sendError'; +import { getLimitMessage } from '../lib/misc/getLimitMessage'; +import { getUploadLimits } from '../lib/misc/getUploadLimits'; +import Settings from '../lib/parser/Settings'; +import Workspace from '../lib/parser/WorkSpace'; +import { UploadedFile } from '../lib/storage/types'; +import GeneratePackagesUseCase from '../usecases/uploads/GeneratePackagesUseCase'; + +const getUploadHandler = (res: express.Response) => { + const maxUploadCount = 21; + return multer({ + limits: getUploadLimits(res.locals.patreon), + dest: process.env.UPLOAD_BASE, + }).array('pakker', maxUploadCount); +}; +class SimpleUploadController { + async handleUpload(req: express.Request, res: express.Response) { + try { + const settings = new Settings(req.body || {}); + + const useCase = new GeneratePackagesUseCase(); + const { packages } = await useCase.execute( + res.locals.patreon, + req.files as UploadedFile[], + settings + ); + + if (packages.length === 0) { + return res.status(400).json({ + error: 'no decks created', + }); + } + + const response: { name: string; link: string }[] = []; + const workspace = new Workspace(true, 'fs'); + const basePath = `/download/${workspace.id}`; + for (const pkg of packages) { + const p = path.join(workspace.location, pkg.name); + fs.writeFileSync(p, pkg.apkg); + response.push({ + name: pkg.name, + link: `${basePath}/${pkg.name}`, + }); + } + + return res.json(response); + } catch (err) { + if (err instanceof Error) { + return res.json({ + error: err.message, + }); + } + } + } + + file(req: express.Request, res: express.Response) { + try { + console.info('uploading file'); + const handleUploadEndpoint = getUploadHandler(res); + + handleUploadEndpoint(req, res, async (error) => { + if (error) { + let msg = error.message; + if (msg === 'File too large') { + msg = getLimitMessage(); + } else { + sendError(error); + } + return res.status(500).send(msg); + } + await this.handleUpload(req, res); + }); + } catch (error) { + sendError(error); + res.status(400); + } + } +} + +export default SimpleUploadController; diff --git a/src/controllers/UploadController.ts b/src/controllers/UploadController.ts index fe1b4b122..8819f56b4 100644 --- a/src/controllers/UploadController.ts +++ b/src/controllers/UploadController.ts @@ -46,7 +46,6 @@ class UploadController { file(req: express.Request, res: express.Response) { try { console.info('uploading file'); - const storage = new StorageHandler(); const handleUploadEndpoint = this.service.getUploadHandler(res); handleUploadEndpoint(req, res, async (error) => { @@ -59,7 +58,7 @@ class UploadController { } return res.status(500).send(msg); } - await this.service.handleUpload(storage, req, res); + await this.service.handleUpload(req, res); }); } catch (error) { sendError(error); diff --git a/src/routes/SimpleUploadRouter.ts b/src/routes/SimpleUploadRouter.ts new file mode 100644 index 000000000..453646cbc --- /dev/null +++ b/src/routes/SimpleUploadRouter.ts @@ -0,0 +1,17 @@ +import express from 'express'; + +import SimpleUploadController from '../controllers/SimpleUploadController'; +import RequireAllowedOrigin from './middleware/RequireAllowedOrigin'; + +const UploadRouter = () => { + const router = express.Router(); + const uploadController = new SimpleUploadController(); + + router.post('/api/simple-upload/file', RequireAllowedOrigin, (req, res) => + uploadController.file(req, res) + ); + + return router; +}; + +export default UploadRouter; diff --git a/src/server.ts b/src/server.ts index add034c94..0bea9803c 100644 --- a/src/server.ts +++ b/src/server.ts @@ -27,6 +27,7 @@ import downloadRouter from './routes/DownloadRouter'; import favoriteRouter from './routes/FavoriteRouter'; import templatesRouter from './routes/TemplatesRouter'; import defaultRouter from './routes/DefaultRouter'; +import simpleUploadRouter from './routes/SimpleUploadRouter'; import { sendError } from './lib/error/sendError'; @@ -71,6 +72,7 @@ const serve = async () => { app.use(downloadRouter()); app.use(favoriteRouter()); app.use(templatesRouter()); + app.use(simpleUploadRouter()); // Note: this has to be the last router app.use(defaultRouter()); diff --git a/src/services/UploadService.ts b/src/services/UploadService.ts index d1b721602..f84f17f7f 100644 --- a/src/services/UploadService.ts +++ b/src/services/UploadService.ts @@ -36,17 +36,13 @@ class UploadService { }).array('pakker', maxUploadCount); } - async handleUpload( - storage: StorageHandler, - req: express.Request, - res: express.Response - ) { + async handleUpload(req: express.Request, res: express.Response) { try { let payload; let plen; const settings = new Settings(req.body || {}); - const useCase = new GeneratePackagesUseCase(storage); + const useCase = new GeneratePackagesUseCase(); const { packages } = await useCase.execute( res.locals.patreon, req.files as UploadedFile[], diff --git a/src/usecases/uploads/GeneratePackagesUseCase.ts b/src/usecases/uploads/GeneratePackagesUseCase.ts index a46b5e0f3..14abbf244 100644 --- a/src/usecases/uploads/GeneratePackagesUseCase.ts +++ b/src/usecases/uploads/GeneratePackagesUseCase.ts @@ -56,8 +56,6 @@ const getPackagesFromZip = async ( }; class GeneratePackagesUseCase { - constructor(private readonly storage: StorageHandler) {} - async execute( isPatreon: boolean, files: UploadedFile[],