publishes any file type, handles 99% for download

This commit is contained in:
jessop 2019-02-06 12:56:28 -05:00
parent 815d0437ac
commit e364dc4024
8 changed files with 87 additions and 69 deletions

View file

@ -60,7 +60,19 @@
"publicDisallowedTypesMain": []
},
"customFileExtensions": {
"application/example-type": "example"
"application/x-troff-man": ".man",
"application/x-troff-me": ".me",
"application/x-mif": ".mif",
"application/x-troff-ms": ".ms",
"application/x-troff": ".roff",
"application/x-python-code": ".pyc",
"text/x-python": ".py",
"application/x-pn-realaudio": ".ram",
"application/x-sgml": ".sgm",
"model/stl": ".stl",
"image/pict": ".pct",
"text/xul": ".xul",
"text/x-go": "go"
}
},
"startup": {

View file

@ -5,8 +5,9 @@ class PublishPreview extends React.Component {
constructor (props) {
super(props);
this.state = {
imgSource : '',
defaultThumbnail: '/assets/img/video_thumb_default.png',
imgSource : '',
defaultVideoThumbnail: '/assets/img/video_thumb_default.png',
defaultThumbnail : '/assets/img/Speech_Logo_Main@OG-02.jpg',
};
}
componentDidMount () {
@ -37,12 +38,13 @@ class PublishPreview extends React.Component {
};
}
setPreviewImageSource (file) {
if (file.type !== 'video/mp4') {
if (this.props.thumbnail) {
this.setPreviewImageSourceFromFile(this.props.thumbnail);
} else if (file.type.substr(0, file.type.indexOf('/')) === 'image'){
this.setPreviewImageSourceFromFile(file);
} else if (file.type === 'video'){
this.setState({imgSource: this.state.defaultVideoThumbnail});
} else {
if (this.props.thumbnail) {
this.setPreviewImageSourceFromFile(this.props.thumbnail);
}
this.setState({imgSource: this.state.defaultThumbnail});
}
}

View file

@ -1,13 +1,13 @@
import React from 'react';
import { validateFile } from '../../utils/file';
import Memeify from '@components/Memeify';
import DropzonePreviewImage from '@components/DropzonePreviewImage';
import DropzoneDropItDisplay from '@components/DropzoneDropItDisplay';
import DropzoneInstructionsDisplay from '@components/DropzoneInstructionsDisplay';
import validateFileForPublish from '@globalutils/validateFileForPublish';
import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { library } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faEdit } from '@fortawesome/free-solid-svg-icons';
const isFacebook = (() => {
@ -29,7 +29,7 @@ class Dropzone extends React.Component {
memeify : false,
};
if(props.file) {
if (props.file) {
// No side effects allowed with `getDerivedStateFromProps`, so
// we must use `componentDidUpdate` and `constructor` routines.
// Note: `FileReader` has an `onloadend` side-effect
@ -133,7 +133,7 @@ class Dropzone extends React.Component {
chooseFile (file) {
if (file) {
try {
validateFile(file); // validate the file's name, type, and size
validateFileForPublish(file); // validate the file's name, type, and size
} catch (error) {
return this.props.setFileError(error.message);
}

View file

@ -47,8 +47,6 @@ const createAssetMetaTags = asset => {
const ogThumbnailContentType = determineContentTypeFromExtension(claimData.thumbnail);
const ogThumbnail = claimData.thumbnail || defaultThumbnail;
console.log('asset.claimData', asset.claimData);
// {property: 'og:title'] = ogTitle},
const metaTags = {
'og:title': ogTitle,

View file

@ -1,9 +1,17 @@
const logger = require('winston');
const mime = require('mime-types');
const {
serving: { customFileExtensions },
} = require('@config/siteConfig');
const getterMethods = {
generated_extension() {
return mime.extension(this.content_type) ? mime.extension(this.content_type) : 'jpg';
logger.info('trying to generate extension', this.content_type);
if (customFileExtensions.hasOwnProperty(this.content_type)) {
return customFileExtensions[this.content_type];
} else {
return mime.extension(this.content_type) ? mime.extension(this.content_type) : 'jpg';
}
},
};

View file

@ -1,5 +1,6 @@
const path = require('path');
const validateFileTypeAndSize = require('./validateFileTypeAndSize.js');
const validateFileForPublish = require('./validateFileForPublish.js');
const parsePublishApiRequestFiles = ({ file, thumbnail }, isUpdate) => {
// make sure a file was provided
@ -40,7 +41,7 @@ const parsePublishApiRequestFiles = ({ file, thumbnail }, isUpdate) => {
}
// validate the file
if (file) validateFileTypeAndSize(file);
if (file) validateFileForPublish(file);
// return results
const obj = {
fileName: file.name,

View file

@ -0,0 +1,38 @@
const logger = require('winston');
const { publishing } = require('@config/siteConfig.json');
const { fileSizeLimits } = publishing;
const SIZE_MB = 1000000;
const validateFileForPublish = file => {
let contentType = file.type;
let mediaType = contentType ? contentType.substr(0, contentType.indexOf('/')) : '';
let mediaTypeLimit = fileSizeLimits[mediaType] || false;
let customLimits = fileSizeLimits['customByContentType'];
if (!file) {
throw new Error('no file provided');
}
if (/'/.test(file.name)) {
throw new Error('apostrophes are not allowed in the file name');
}
if (Object.keys(customLimits).includes(contentType)) {
if (file.size > customLimits[contentType]) {
throw new Error(
`Sorry, type ${contentType} is limited to ${customLimits[contentType] / SIZE_MB} MB.`
);
}
}
if (mediaTypeLimit) {
if (file.size > mediaTypeLimit) {
throw new Error(`Sorry, type ${mediaType} is limited to ${mediaTypeLimit / SIZE_MB} MB.`);
}
}
return file;
};
module.exports = validateFileForPublish;

View file

@ -1,22 +1,14 @@
import { publishing } from '@config/siteConfig.json';
const {
fileSizeLimits: {
image: maxSizeImage = 10000000,
video: maxSizeVideo = 50000000,
audio: maxSizeAudio = 50000000,
text: maxSizeText = 50000000,
model: maxSizeModel = 50000000,
application: maxSizeApplication = 50000000,
customByContentType,
},
} = publishing;
const { fileSizeLimits } = publishing;
const SIZE_MB = 1000000;
export const validateFileForPublish = file => {
export default function validateFileForPublish(file) {
let contentType = file.type;
let mediaType = contentType ? contentType.substr(0, contentType.indexOf('/')) : '';
let mediaTypeLimit = fileSizeLimits[mediaType] || false;
let customLimits = fileSizeLimits['customByContentType'];
if (!file) {
throw new Error('no file provided');
@ -26,50 +18,17 @@ export const validateFileForPublish = file => {
throw new Error('apostrophes are not allowed in the file name');
}
if (Object.keys(customByContentType).includes(contentType)) {
if (file.size > customByContentType[contentType]) {
if (Object.keys(customLimits).includes(contentType)) {
if (file.size > customLimits[contentType]) {
throw new Error(
`Sorry, type ${contentType} is limited to ${customByContentType[contentType] / SIZE_MB} MB.`
`Sorry, type ${contentType} is limited to ${customLimits[contentType] / SIZE_MB} MB.`
);
}
} else {
switch (mediaType) {
case 'image':
if (file.size > maxSizeImage) {
throw new Error(`Sorry, type ${mediaType} is limited to ${maxSizeImage / SIZE_MB} MB.`);
}
break;
case 'audio':
if (file.size > maxSizeAudio) {
throw new Error(`Sorry, type ${mediaType} is limited to ${maxSizeAudio / SIZE_MB} MB.`);
}
break;
case 'video':
if (file.size > maxSizeVideo) {
throw new Error(`Sorry, type ${mediaType} is limited to ${maxSizeVideo / SIZE_MB} MB.`);
}
break;
case 'text':
if (file.size > maxSizeText) {
throw new Error(`Sorry, type ${mediaType} is limited to ${maxSizeText / SIZE_MB} MB.`);
}
break;
case 'model':
if (file.size > maxSizeModel) {
throw new Error(`Sorry, type ${mediaType} is limited to ${maxSizeModel / SIZE_MB} MB.`);
}
break;
case 'application':
if (file.size > maxSizeApplication) {
throw new Error(
`Sorry, type ${mediaType} is limited to ${maxSizeApplication / SIZE_MB} MB.`
);
}
break;
default:
throw new Error(`Missing or unrecognized file type`);
}
if (mediaTypeLimit) {
if (file.size > mediaTypeLimit) {
throw new Error(`Sorry, type ${mediaType} is limited to ${mediaTypeLimit / SIZE_MB} MB.`);
}
return false;
}
return file;
};
}