Skip to content

Commit

Permalink
Merge pull request #413 from mayeaux/add-thumbnail-upload
Browse files Browse the repository at this point in the history
Add thumbnail upload
  • Loading branch information
mayeaux authored Apr 27, 2021
2 parents 5ce51ef + aec77c7 commit 4211029
Show file tree
Hide file tree
Showing 11 changed files with 705 additions and 406 deletions.
1 change: 1 addition & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ if(cluster.isMaster){
requestPath === '/upload' ||
requestPath === '/account/profile' ||
requestPath === '/api/channel/thumbnail/delete' ||
requestPath === '/api/uploadFileThumbnail' ||
requestPath.match(editUploadRegexp) ||
requestPath.match(deleteUploadThumbnailRegexp) ||
requestPath === '/livestream/on-live-auth' ||
Expand Down
125 changes: 113 additions & 12 deletions controllers/backend/uploading.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const path = require('path');
const mkdirp = Promise.promisifyAll(require('mkdirp'));
var randomstring = require('randomstring');
var CombinedStream = require('combined-stream');
const FileType = require('file-type');
const readChunk = require('read-chunk');

const redisClient = require('../../config/redis');

Expand Down Expand Up @@ -165,7 +167,8 @@ function testIfUserRestricted(user, logObject, res){
function aboutToProcess(res, channelUrl, uniqueTag){
res.send({
message: 'ABOUT TO PROCESS',
url: `/user/${channelUrl}/${uniqueTag}?u=t`
url: `/user/${channelUrl}/${uniqueTag}?u=t`,
uniqueTag
});
}

Expand Down Expand Up @@ -417,6 +420,8 @@ exports.postFileUpload = async(req, res) => {

uploadLogger.info('Concat done', logObject);

// TODO: pull this out into its own function

let bitrate, codecName, codecProfile;

if(upload.fileType !== 'image'){
Expand Down Expand Up @@ -587,25 +592,32 @@ exports.postFileUpload = async(req, res) => {

uploadLogger.info('Upload marked as complete', logObject);

updateUsersUnreadSubscriptions(user);

uploadLogger.info('Updated subscribed users subscriptions', logObject);

// this is admin upload for all
alertAdminOfNewUpload(user, upload);

uploadLogger.info('Alert admins of a new upload', logObject);

if(upload.visibility == 'public'){
// update user push notifications
updateUsersPushNotifications(user, upload);
// if visibility is public, send push and email notifications
if(upload.visibility === 'public'){

// update the subscription amount of subscribing users
updateUsersUnreadSubscriptions(user);

uploadLogger.info('Updated subscribed users subscriptions', logObject);

// send push and email notifs if production
if(process.env.NODE_ENV === 'production'){
// update user push notifications
updateUsersPushNotifications(user, upload);

uploadLogger.info('Update users push notifications', logObject);
uploadLogger.info('Update users push notifications', logObject);

// update user email notifications
updateUsersEmailNotifications(user, upload, req.host);
// update user email notifications
updateUsersEmailNotifications(user, upload, req.host);

uploadLogger.info('Update users email notifications', logObject);
}

uploadLogger.info('Update users email notifications', logObject);
}

// upload is complete, send it off to user (aboutToProcess is a misnomer here)
Expand Down Expand Up @@ -732,3 +744,92 @@ exports.adminUpload = async(req, res) => {
// });

};

/**
* POST /api/uploadFileThumbnail
* Upload file thumbnail
*/
exports.postThumbnailUpload = async(req, res) => {
console.log('files');
console.log(req.files);

console.log('body');
console.log(req.body);

const uniqueTag = req.body.uploadUniqueTag;

// check if there's a thumbnail
let thumbnailFile;

// if req there are files and
if(req.files && req.files.thumbnailFile){
thumbnailFile = req.files.thumbnailFile;
} else {
res.status(500);
return res.send('no thumbnail file');
}

const filename = thumbnailFile.originalFilename;
// size in bytes
const fileSize = thumbnailFile.size;

// 5 MB
if(fileSize > 5242880){
res.status(500);
return res.send('file too large');
}

const filePath = thumbnailFile.path;

const buffer = readChunk.sync(filePath, 0, 4100);

const bufferFileType = await FileType.fromBuffer(buffer);

console.log('Buffer file type ' + bufferFileType);

// comes back at 'mp4' to prepend . to make .mp4
const extension = '.' + String(bufferFileType.ext);

console.log('extension');
console.log(extension);

const fileType = getMediaType('hackforsetup' + extension);

if(fileType !== 'image'){
res.status(500);
return res.send('not an image');
}

console.log('File type');
console.log(fileType);

console.log(bufferFileType);

const channelUrl = req.user.channelUrl;

const saveFileDirectory = `${saveAndServeFilesDirectory}/${channelUrl}/${uniqueTag}-custom${extension}`;

await fs.move(filePath, saveFileDirectory);

const upload = await Upload.findOne({ uniqueTag });

if(!upload.thumbnails){
upload.thumbnails = {};
}

upload.thumbnails.custom = `${uniqueTag}-custom${extension}`;

if(process.env.UPLOAD_TO_B2 === 'true'){
// TODO: check this
// await backblaze.editploadThumbnailToB2(req.user.channelUrl, upload.uniqueTag, extension, saveFileDirectory);
}

// sendUploadThumbnailToB2(args)

await upload.save();

res.status(200);

return res.send('success');

};
45 changes: 8 additions & 37 deletions controllers/frontend/account.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ const forgotEmailFunctionalityOn = process.env.FORGOT_PASSWORD_EMAIL_FUNCTIONALI

const { attachDataToUploadsAsUploads } = require('../../lib/helpers/addFieldsToUploads');

const stripeToken = process.env.STRIPE_FRONTEND_TOKEN;

const plusEnabled = process.env.PLUS_ENABLED === 'true';

const verifyEmailFunctionalityOn = process.env.CONFIRM_EMAIL_FUNCTIONALITY_ON === 'true';

// TODO: pull this function out
function removeTrailingSlash(requestPath){
if(requestPath.charAt(requestPath.length - 1) == '/'){
Expand All @@ -68,37 +74,6 @@ function removeTrailingSlash(requestPath){
return requestPath;
}

// TODO: pull this function out
async function addValuesIfNecessary(upload, channelUrl){
if(upload.fileType == 'video' || upload.fileType == 'audio'){
if(!upload.durationInSeconds || !upload.formattedDuration){

var server = uploadServer;
if(server.charAt(0) == '/') // the slash confuses the file reading, because host root directory is not the same as machine root directory
server = server.substr(1);

const uploadLocation = `${server}/${channelUrl}/${upload.uniqueTag + upload.fileExtension}`;

try {
const duration = await getUploadDuration(uploadLocation, upload.fileType);
console.log(duration);

let uploadDocument = await Upload.findOne({uniqueTag: upload.uniqueTag});

uploadDocument.durationInSeconds = duration.seconds;
uploadDocument.formattedDuration = duration.formattedTime;

await uploadDocument.save();

} catch(err){
/** if the file has been deleted then it won't blow up **/
// console.log(err);
}
// console.log('have to add');
}
}
}

/**
* GET /upload
* Page to facilitate user uploads
Expand All @@ -124,7 +99,8 @@ exports.getFileUpload = async(req, res) => {
categories,
maxRatingAllowed: process.env.MAX_RATING_ALLOWED,
userCanUploadContentOfThisRating,
secondsToFormattedTime
secondsToFormattedTime,
plusEnabled
});
};

Expand Down Expand Up @@ -903,11 +879,6 @@ exports.getSignup = (req, res) => {
* Account page.
*/
exports.getAccount = async(req, res) => {
const stripeToken = process.env.STRIPE_FRONTEND_TOKEN;

const plusEnabled = process.env.PLUS_ENABLED == 'true';

const verifyEmailFunctionalityOn = process.env.CONFIRM_EMAIL_FUNCTIONALITY_ON == 'true';

// give user an upload token
if(!req.user.uploadToken){
Expand Down
13 changes: 12 additions & 1 deletion controllers/frontend/mediaPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,14 @@ function getFormattedFileSize(upload){
*/
exports.getMedia = async(req, res) => {

// TODO: pull out plus redirect thing

// get the amount of slashes, to determine if the user is allowed
// to access the vanity url version of this url
let requestPath = req.path;

var queryParams = req.url.split('?')[1];

if(requestPath.charAt(requestPath.length - 1) == '/'){
requestPath = requestPath.substr(0, requestPath.length - 1);
}
Expand Down Expand Up @@ -118,10 +122,17 @@ exports.getMedia = async(req, res) => {
});
}

// console.log(req.path);

// TODO: make sure to add query params here
// if it's three but you're plus, then move to shortened url
if(amountOfSlashes === 3 && user.plan == 'plus'){
return res.redirect(`/${user.channelUrl}/${upload.uniqueTag}`);
let redirectPath = `/${user.channelUrl}/${upload.uniqueTag}`;
if(queryParams){
redirectPath = redirectPath + '?' + queryParams;
}

return res.redirect(redirectPath);
}

// TODO: pull this thing out
Expand Down
26 changes: 26 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
"paypal-rest-sdk": "^1.8.1",
"pug": "^2.0.3",
"randomstring": "^1.1.5",
"read-chunk": "^3.2.0",
"recaptcha2": "^1.3.3",
"redis": "^2.8.0",
"request": "^2.88.0",
Expand Down
1 change: 1 addition & 0 deletions routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ function frontendRoutes(app){
app.post('/api/upload/:uniqueTag/edit', passportConfig.isAuthenticated, internalApiController.editUpload);
app.post('/api/upload/:uniqueTag/thumbnail/delete', passportConfig.isAuthenticated, internalApiController.deleteUploadThumbnail);
app.post('/api/upload/:uniqueTag/captions/delete', passportConfig.isAuthenticated, internalApiController.deleteUploadCaption);
app.post('/api/uploadFileThumbnail', passportConfig.isAuthenticated, uploadingController.postThumbnailUpload);

/** API ENDPOINTS **/
app.post('/api/react/:upload/:user', passportConfig.isAuthenticated, internalApiController.react);
Expand Down
Loading

0 comments on commit 4211029

Please sign in to comment.