Skip to content

Commit

Permalink
Merge pull request #98 from WildCodeSchool/files-download-service
Browse files Browse the repository at this point in the history
File preview in visitor download ok
  • Loading branch information
VincentRssx authored Dec 12, 2024
2 parents 6ba1001 + d1c652c commit 30b9dd8
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 181 deletions.
1 change: 1 addition & 0 deletions files/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"express": "^4.18.2",
"graphql": "^16.9.0",
"jsonwebtoken": "^9.0.2",
"mime": "^4.0.4",
"multer": "^1.4.5-lts.1",
"ts-node-dev": "^2.0.0",
"uuid": "^11.0.2"
Expand Down
254 changes: 146 additions & 108 deletions files/src/controllers/filesController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,90 +25,90 @@ if (!fs.existsSync(FINAL_DIR)) {
}

export const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, TEMP_DIR);
},
filename: (req, file, cb) => {
const fileUuid = uuidv4();
const fileExtension = path.extname(file.originalname);
const newFilename = `${fileUuid}${fileExtension}`;
(file as any).original_name = file.originalname;
cb(null, newFilename);
},
destination: (req, file, cb) => {
cb(null, TEMP_DIR);
},
filename: (req, file, cb) => {
const fileUuid = uuidv4();
const fileExtension = path.extname(file.originalname);
const newFilename = `${fileUuid}${fileExtension}`;

(file as any).original_name = file.originalname;

cb(null, newFilename);
},
});

const upload = multer({storage}).array("files", 10);

// This function works but it's WAY too long, we will need to refactor it someday
export const addNewUpload = async (req: Request, res: any) => {
upload(req, res, async (err) => {
if (err) {
return res.status(500).send("Error uploading files.");
}

if (!req.files || req.files.length === 0) {
return res.status(400).send("No files uploaded.");
}

const filesArray = req.files as Express.Multer.File[];
const validFiles = [];

for (const file of filesArray) {
const fileUuid = uuidv4();
const fileExtension = path.extname(file.originalname);
const fileFinalName = `${fileUuid}${fileExtension}`;
const tempPath = file.path;
const finalPath = path.join(FINAL_DIR, fileFinalName);

const isValid = await validateFile(file, tempPath);
if (isValid) {
fs.renameSync(tempPath, finalPath);
validFiles.push({
original_name: (file as any).original_name || file.originalname,
default_name: fileFinalName,
path: finalPath,
size: file.size,
uuid: fileUuid,
upload(req, res, async (err) => {
if (err) {
return res.status(500).send("Error uploading files.");
}

if (!req.files || req.files.length === 0) {
return res.status(400).send("No files uploaded.");
}

const filesArray = req.files as Express.Multer.File[];
const validFiles = [];

for (const file of filesArray) {
const fileUuid = uuidv4();
const fileExtension = path.extname(file.originalname);
const fileFinalName = `${fileUuid}${fileExtension}`;
const tempPath = file.path;
const finalPath = path.join(FINAL_DIR, fileFinalName);

const isValid = await validateFile(file, tempPath);
if (isValid) {
fs.renameSync(tempPath, finalPath);
validFiles.push({
original_name: (file as any).original_name || file.originalname,
default_name: fileFinalName,
path: finalPath,
size: file.size,
uuid: fileUuid,
mimetype: file.mimetype,
});
} else {
fs.unlinkSync(tempPath);
}
}

if (validFiles.length > 0) {
axios.post("http://backend:4000/graphql", {
query: ADD_ONE_UPLOAD,
variables: {
senderEmail: req.body.senderEmail,
receiversEmails: Array.isArray(req.body.receiversEmails)
? req.body.receiversEmails
: [req.body.receiversEmails],
title: req.body.title || "Default Title",
message: req.body.message || "Default Message",
fileData: JSON.stringify(validFiles),
},
})
.then((response) => {
console.log("DATA:", response.data);
res.status(200).json(response.data);
})
.catch((err) => {
if (err.response && err.response.data) {
console.error("GraphQL Errors:", err.response.data.errors);
} else {
console.error("Unexpected Error:", err);
}
res.status(500).send("Error during file upload mutation.");
});
} else {
res.status(400).send("No valid files uploaded.");
}
});
});
} else {
fs.unlinkSync(tempPath);
}
}

if (validFiles.length > 0) {
axios.post("http://backend:4000/graphql", {
query: ADD_ONE_UPLOAD,
variables: {
senderEmail: req.body.senderEmail,
receiversEmails: Array.isArray(req.body.receiversEmails)
? req.body.receiversEmails
: [req.body.receiversEmails],
title: req.body.title || "Default Title",
message: req.body.message || "Default Message",
fileData: JSON.stringify(validFiles),
},
})
.then((response) => {
console.log("DATA:", response.data);
res.status(200).json(response.data);
})
.catch((err) => {
if (err.response && err.response.data) {
console.error("GraphQL Errors:", err.response.data.errors);
} else {
console.error("Unexpected Error:", err);
}
res.status(500).send("Error during file upload mutation.");
});
} else {
res.status(400).send("No valid files uploaded.");
}
});
};


export const deleteFile = async (req: Request, res: any) => {
const filename = req.query.filename
Expand All @@ -130,39 +130,77 @@ export const deleteFile = async (req: Request, res: any) => {
}

export const downloadFiles = async (req: Request, res: any) => {
const FILES_DIR = path.join(__dirname, "../uploads/final");
const files = req.body.files as string[];

if (!files || files.length === 0) {
return res.status(400).send("No files provided.");
}

res.setHeader("Content-Type", "application/zip");
res.attachment("files.zip");

const archive = archiver("zip", { zlib: { level: 9 } });

archive.on("error", (err) => {
res.status(500).send("Error creating ZIP archive.");
});

archive.pipe(res);

for (const file of files) {
const filePath = path.join(FILES_DIR, file);
if (fs.existsSync(filePath)) {
archive.file(filePath, { name: file });
} else {
console.warn(`File not found: ${file}`);
}
}

try {
await archive.finalize();
} catch (err) {
res.status(500).send("Error finalizing ZIP archive.");
}
const FILES_DIR = path.join(__dirname, "../uploads/final");
const files = req.body.files as string[];

if (!files || files.length === 0) {
return res.status(400).send("No files provided.");
}

res.setHeader("Content-Type", "application/zip");
res.attachment("files.zip");

const archive = archiver("zip", {zlib: {level: 9}});

archive.on("error", (err) => {
res.status(500).send("Error creating ZIP archive.");
});

archive.pipe(res);

for (const file of files) {
const filePath = path.join(FILES_DIR, file);
if (fs.existsSync(filePath)) {
archive.file(filePath, {name: file});
} else {
console.warn(`File not found: ${file}`);
}
}

try {
await archive.finalize();
} catch (err) {
res.status(500).send("Error finalizing ZIP archive.");
}
};

export const getOneFile = (req: Request, res: any) => {
try {
const {fileDefaultName} = req.body;

console.log(fileDefaultName)

if (!fileDefaultName) {
return res.status(400).send("File path is required.");
}

const fullPath = path.join(FINAL_DIR, fileDefaultName);

console.log(fullPath)

if (!fs.existsSync(fullPath)) {
return res.status(404).send("File not found.");
}

res.setHeader("Content-Type", "application/octet-stream");
res.setHeader(
"Content-Disposition",
`inline; filename="${path.basename(fullPath)}"`
);

const fileStream = fs.createReadStream(fullPath);
fileStream.pipe(res);

fileStream.on("error", (err) => {
console.error("Error streaming file:", err);
res.status(500).send("Error sending file.");
});
} catch (err) {
console.error(err);
res.status(500).send("Error fetching file for preview.");
}
};




6 changes: 4 additions & 2 deletions files/src/router/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import express from "express";
import {addNewUpload, deleteFile, downloadFiles} from "../controllers/filesController";
import {addNewUpload, deleteFile, downloadFiles, getOneFile} from "../controllers/filesController";

const router = express.Router()

router.post('/get-one', getOneFile)
router.post('/upload', addNewUpload)
router.post('/download', downloadFiles)

router.delete('/delete', deleteFile)
// blob:http://localhost:7002/files/f6b04590-02f1-45db-a7e7-ec9ee352ef4f

router.post('/download', downloadFiles)

export default router
Loading

0 comments on commit 30b9dd8

Please sign in to comment.