Files
classroomio/apps/backend/src/routes/uploadVideo.js
T
Adeyemi AdetunjiandRotimi Best 3a22a73380 feat: add classroomio's server to the monorepo (#168)
* add classroomio server to apps

* ReadME upadte

* Update README.md

* rename project to backend

* fix lock file

---------

Co-authored-by: Rotimi Best <best@classroomio.com>
2024-02-28 03:25:25 +01:00

252 lines
6.5 KiB
JavaScript

const express = require('express');
const FormData = require('form-data');
const axios = require('axios');
// const Queue = require('bull');
const { promisify } = require('util');
const fs = require('fs');
const unlinkAsync = promisify(fs.unlink);
const {
S3Client,
PutObjectCommand,
// GetObjectCommand,
} = require('@aws-sdk/client-s3');
// const { getSupabase } = require('../utils/supabase');
const genUniqueId = require('../utils/genUniqueId');
const upload = require('../utils/upload');
const {
CLOUDFLARE_ACCESS_KEY,
CLOUDFLARE_SECRET_ACCESS_KEY,
CLOUDFLARE_ACCOUNT_ID,
CLOUDFLARE_PUBLIC_ACCOUNT_ID,
MUSE_API_KEY,
} = process.env;
const router = express.Router();
const S3 = new S3Client({
region: 'auto',
endpoint: `https://${CLOUDFLARE_ACCOUNT_ID}.r2.cloudflarestorage.com`,
credentials: {
accessKeyId: CLOUDFLARE_ACCESS_KEY,
secretAccessKey: CLOUDFLARE_SECRET_ACCESS_KEY,
},
});
// const supabase = getSupabase();
// const museUploadQueue = new Queue('video', process.env.REDIS_API_KEY, {
// redis: { tls: { rejectUnauthorized: false } },
// });
router.post('/', upload.single('videoFile'), async (req, res) => {
const {
file,
query: { lessonId },
} = req;
console.log('lessonId', lessonId);
console.log('file', file);
if (!file?.fieldname || !file?.fieldname) {
return res.status(400).json({
success: false,
message: 'You must provide a file to upload',
});
}
if (file?.size > 30 * 1024 * 1024) {
return res.status(400).json({
success: false,
type: 'FILE_TOO_LARGE',
message: 'File is too large',
});
}
const fileData = fs.readFileSync(file.path);
const fileName = `${genUniqueId()}-${file.originalname}`;
const params = {
Bucket: 'videos',
Key: fileName,
Body: fileData,
};
const fileUrl = `https://pub-${CLOUDFLARE_PUBLIC_ACCOUNT_ID}.r2.dev/${fileName}`;
let metadata = {};
try {
const s3Upload = S3.send(new PutObjectCommand(params));
const museUpload = uploadToMuseNow(fileData, file.originalname);
Promise.all([s3Upload, museUpload]).then((values) => {
const [s3UploadRes, museUploadRes] = values;
// Delete file saved by mutler in file
unlinkAsync(file.path);
console.log('s3UploadRes', s3UploadRes);
console.log('museUploadRes', museUploadRes);
if (museUploadRes.metadata) {
metadata = museUploadRes.metadata;
}
res.json({
success: true,
url: fileUrl,
metadata,
message: 'Uploaded successfully',
});
});
} catch (error) {
// error handling.
const { requestId, cfId, extendedRequestId } = error.$$metadata || {};
console.error('Error uploading file', error);
console.log({ requestId, cfId, extendedRequestId });
res.json({
success: false,
message: 'Uploaded failed: ' + error,
});
} finally {
// finally.
console.log('File upload complete');
// console.log('Add muse queue');
// museUploadQueue.add({
// fileName,
// originalFileName: file.originalname,
// lessonId,
// fileUrl,
// unlinkPath: file.path,
// });
}
});
router.get('/', (req, res) => {
res.send('Get upload video');
});
async function uploadToMuseNow(fileData, fileName) {
try {
// Add file data to form
const form = new FormData();
form.append('file', fileData, fileName);
// Send to muse through axios - fetch is a pain in the ass
const response = await axios({
method: 'POST',
url: 'https://api.muse.ai/api/files/upload',
data: form,
maxContentLength: Infinity,
maxBodyLength: Infinity,
headers: {
Key: MUSE_API_KEY,
},
});
return {
metadata: response.data,
};
} catch (error) {
console.log('Upload to Muse failed', error?.response?.data);
return {};
}
}
// /**
// * Uploads video to muse.ai and store response in DB
// *
// * @param {Blod} s3Data AWS s3 data
// * @param {string} fileName Name of the file
// * @param {string} lessonId Associated lesson this video was uploaded to
// * @param {string} fileUrl URL to the video in s3
// * @param {string} unlinkPath Path to mutler file to delete
// */
// async function uploadToMuse(s3Key, fileName, lessonId, fileUrl, unlinkPath) {
// try {
// await unlinkAsync(unlinkPath);
// const s3Data = await S3.send(
// new GetObjectCommand({
// Bucket: 'videos',
// Key: s3Key,
// })
// );
// // Add file data to form
// const form = new FormData();
// form.append('file', s3Data.Body, fileName);
// // Send to muse through axios - fetch is a pain in the ass
// const response = await axios({
// method: 'POST',
// url: 'https://api.muse.ai/api/files/upload',
// data: form,
// maxContentLength: Infinity,
// maxBodyLength: Infinity,
// headers: {
// Key: MUSE_API_KEY,
// },
// });
// console.log('Upload to muse complete', response.data);
// const { data: lesson } = await supabase
// .from('lesson')
// .select(`*`)
// .eq('id', lessonId)
// .single();
// if (lesson) {
// console.log('Found lesson');
// // Add Muse response to metadata
// const videos = lesson.videos.map((v) => {
// if (v.link === fileUrl) {
// console.log('matches');
// v.metadata = JSON.parse(JSON.stringify(response.data));
// }
// return v;
// });
// // Save uploaded data to DB
// const { error } = await supabase
// .from('lesson')
// .update({ videos })
// .eq('id', lessonId)
// .select();
// if (error) {
// console.log('Error updating lesson', error);
// } else {
// console.log('Update DB complete');
// }
// }
// } catch (error) {
// console.log('Upload to Muse failed', error?.response?.data);
// }
// }
// // Queue to Upload to muse.ai
// museUploadQueue.process(async function (job, done) {
// console.log('Initilizing Muse Request\n\n', job.data);
// const { fileName, originalFileName, lessonId, fileUrl, unlinkPath } =
// job.data;
// await uploadToMuse(fileName, originalFileName, lessonId, fileUrl, unlinkPath);
// done();
// });
// museUploadQueue.on('completed', function (job) {
// // Job completed with output result!
// console.log('Completed all jobs in uploading to muse', job.data);
// });
// museUploadQueue.on('error', function (error) {
// // Job completed with output result!
// console.log('error on queue', error);
// });
module.exports = router;