2020-10-02 20:44:29 +08:00
|
|
|
/* eslint key-spacing: 0 */
|
|
|
|
/* eslint quote-props: 0 */
|
|
|
|
|
2021-03-16 23:49:14 +08:00
|
|
|
import { isNonEmptyArray } from 'Common/Utils';
|
|
|
|
|
2020-10-02 20:44:29 +08:00
|
|
|
const
|
|
|
|
cache = {},
|
|
|
|
app = 'application/',
|
|
|
|
msOffice = app+'vnd.openxmlformats-officedocument.',
|
|
|
|
openDoc = app+'vnd.oasis.opendocument.',
|
2020-10-03 20:02:33 +08:00
|
|
|
sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB'],
|
2020-10-02 20:44:29 +08:00
|
|
|
|
|
|
|
exts = {
|
2021-03-25 04:26:40 +08:00
|
|
|
eml: 'message/rfc822',
|
|
|
|
mime: 'message/rfc822',
|
|
|
|
rtx: 'text/richtext',
|
|
|
|
vcard: 'text/vcard',
|
|
|
|
vcf: 'text/vcard',
|
|
|
|
htm: 'text/html',
|
|
|
|
html: 'text/html',
|
|
|
|
csv: 'text/csv',
|
|
|
|
ics: 'text/calendar',
|
|
|
|
ifb: 'text/calendar',
|
|
|
|
xml: 'text/xml',
|
|
|
|
json: app+'json',
|
|
|
|
p10: app+'pkcs10',
|
|
|
|
p7c: app+'pkcs7-mime',
|
|
|
|
p7m: app+'pkcs7-mime',
|
|
|
|
p7s: app+'pkcs7-signature',
|
|
|
|
torrent: app+'x-bittorrent',
|
2020-10-02 20:44:29 +08:00
|
|
|
|
|
|
|
// scripts
|
2021-03-25 04:26:40 +08:00
|
|
|
js: app+'javascript',
|
|
|
|
pl: 'text/perl',
|
|
|
|
css: 'text/css',
|
|
|
|
asp: 'text/asp',
|
|
|
|
php: app+'x-httpd-php',
|
|
|
|
phtml: app+'x-httpd-php',
|
2020-10-02 20:44:29 +08:00
|
|
|
|
|
|
|
// images
|
2021-03-25 04:26:40 +08:00
|
|
|
jpg: 'image/jpeg',
|
|
|
|
ico: 'image/x-icon',
|
|
|
|
tif: 'image/tiff',
|
|
|
|
svg: 'image/svg+xml',
|
|
|
|
svgz: 'image/svg+xml',
|
2020-10-02 20:44:29 +08:00
|
|
|
|
|
|
|
// archives
|
2021-03-25 04:26:40 +08:00
|
|
|
zip: app+'zip',
|
2020-10-02 20:44:29 +08:00
|
|
|
'7z': app+'x-7z-compressed',
|
2021-03-25 04:26:40 +08:00
|
|
|
rar: app+'x-rar-compressed',
|
|
|
|
cab: app+'vnd.ms-cab-compressed',
|
|
|
|
gz: app+'x-gzip',
|
|
|
|
tgz: app+'x-gzip',
|
|
|
|
bz: app+'x-bzip',
|
|
|
|
bz2: app+'x-bzip2',
|
|
|
|
deb: app+'x-debian-package',
|
2020-10-02 20:44:29 +08:00
|
|
|
|
|
|
|
// audio
|
2021-03-25 04:26:40 +08:00
|
|
|
mp3: 'audio/mpeg',
|
|
|
|
wav: 'audio/x-wav',
|
|
|
|
mp4a: 'audio/mp4',
|
|
|
|
weba: 'audio/webm',
|
|
|
|
m3u: 'audio/x-mpegurl',
|
2020-10-02 20:44:29 +08:00
|
|
|
|
|
|
|
// video
|
2021-03-25 04:26:40 +08:00
|
|
|
qt: 'video/quicktime',
|
|
|
|
mov: 'video/quicktime',
|
|
|
|
wmv: 'video/windows-media',
|
|
|
|
avi: 'video/x-msvideo',
|
2020-10-02 20:44:29 +08:00
|
|
|
'3gp': 'video/3gpp',
|
|
|
|
'3g2': 'video/3gpp2',
|
2021-03-25 04:26:40 +08:00
|
|
|
mp4v: 'video/mp4',
|
|
|
|
mpg4: 'video/mp4',
|
|
|
|
ogv: 'video/ogg',
|
|
|
|
m4v: 'video/x-m4v',
|
|
|
|
asf: 'video/x-ms-asf',
|
|
|
|
asx: 'video/x-ms-asf',
|
|
|
|
wm: 'video/x-ms-wm',
|
|
|
|
wmx: 'video/x-ms-wmx',
|
|
|
|
wvx: 'video/x-ms-wvx',
|
|
|
|
movie: 'video/x-sgi-movie',
|
2020-10-02 20:44:29 +08:00
|
|
|
|
|
|
|
// adobe
|
2021-03-25 04:26:40 +08:00
|
|
|
pdf: app+'pdf',
|
|
|
|
psd: 'image/vnd.adobe.photoshop',
|
|
|
|
ai: app+'postscript',
|
|
|
|
eps: app+'postscript',
|
|
|
|
ps: app+'postscript',
|
2020-10-02 20:44:29 +08:00
|
|
|
|
|
|
|
// ms office
|
2021-03-25 04:26:40 +08:00
|
|
|
doc: app+'msword',
|
|
|
|
rtf: app+'rtf',
|
|
|
|
xls: app+'vnd.ms-excel',
|
|
|
|
ppt: app+'vnd.ms-powerpoint',
|
|
|
|
docx: msOffice+'wordprocessingml.document',
|
|
|
|
xlsx: msOffice+'spreadsheetml.sheet',
|
|
|
|
dotx: msOffice+'wordprocessingml.template',
|
|
|
|
pptx: msOffice+'presentationml.presentation',
|
2020-10-02 20:44:29 +08:00
|
|
|
|
|
|
|
// open office
|
2021-03-25 04:26:40 +08:00
|
|
|
odt: openDoc+'text',
|
|
|
|
ods: openDoc+'spreadsheet',
|
|
|
|
odp: openDoc+'presentation'
|
2020-10-02 20:44:29 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
export const FileType = {
|
|
|
|
Unknown: 'unknown',
|
|
|
|
Text: 'text',
|
|
|
|
Html: 'html',
|
|
|
|
Code: 'code',
|
|
|
|
Eml: 'eml',
|
|
|
|
WordText: 'word-text',
|
|
|
|
Pdf: 'pdf',
|
|
|
|
Image: 'image',
|
|
|
|
Audio: 'audio',
|
|
|
|
Video: 'video',
|
|
|
|
Sheet: 'sheet',
|
|
|
|
Presentation: 'presentation',
|
|
|
|
Certificate: 'certificate',
|
|
|
|
CertificateBin: 'certificate-bin',
|
|
|
|
Archive: 'archive'
|
|
|
|
};
|
|
|
|
|
2021-02-17 21:40:21 +08:00
|
|
|
export const FileInfo = {
|
2020-10-02 20:44:29 +08:00
|
|
|
/**
|
|
|
|
* @param {string} fileName
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
getExtension: fileName => {
|
|
|
|
fileName = fileName.toLowerCase().trim();
|
|
|
|
const result = fileName.split('.').pop();
|
|
|
|
return result === fileName ? '' : result;
|
|
|
|
},
|
|
|
|
|
|
|
|
getContentType: fileName => {
|
|
|
|
fileName = fileName.toLowerCase().trim();
|
|
|
|
if ('winmail.dat' === fileName) {
|
2021-02-22 22:16:33 +08:00
|
|
|
return app + 'ms-tnef';
|
2020-10-02 20:44:29 +08:00
|
|
|
}
|
|
|
|
let ext = fileName.split('.').pop();
|
|
|
|
if (/^(txt|text|def|list|in|ini|log|sql|cfg|conf|asc)$/.test(ext))
|
|
|
|
return 'text/plain';
|
|
|
|
if (/^(mpe?g|mpe|m1v|m2v)$/.test(ext))
|
|
|
|
return 'video/mpeg';
|
|
|
|
if (/^aif[cf]?$/.test(ext))
|
|
|
|
return 'audio/aiff';
|
|
|
|
if (/^(aac|flac|midi|ogg)$/.test(ext))
|
|
|
|
return 'audio/'+ext;
|
|
|
|
if (/^(h26[134]|jpgv|mp4|webm)$/.test(ext))
|
|
|
|
return 'video/'+ext;
|
2021-02-17 21:40:21 +08:00
|
|
|
if (/^(otf|sfnt|ttf|woff2?)$/.test(ext))
|
|
|
|
return 'font/'+ext;
|
2020-10-02 20:44:29 +08:00
|
|
|
if (/^(png|jpeg|gif|tiff|webp)$/.test(ext))
|
|
|
|
return 'image/'+ext;
|
|
|
|
|
|
|
|
return exts[ext] || app+'octet-stream';
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {string} sExt
|
|
|
|
* @param {string} sMimeType
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
getType: (ext, mimeType) => {
|
|
|
|
ext = ext.toLowerCase().trim();
|
|
|
|
mimeType = mimeType.toLowerCase().trim().replace('csv/plain', 'text/csv');
|
|
|
|
|
|
|
|
let key = ext + mimeType;
|
|
|
|
if (cache[key]) {
|
|
|
|
return cache[key];
|
|
|
|
}
|
|
|
|
|
|
|
|
let result = FileType.Unknown;
|
|
|
|
const mimeTypeParts = mimeType.split('/'),
|
2021-01-27 07:26:31 +08:00
|
|
|
type = mimeTypeParts[1].replace('x-','').replace('-compressed',''),
|
2021-02-22 22:16:33 +08:00
|
|
|
match = str => mimeType.includes(str),
|
|
|
|
archive = /^(zip|7z|tar|rar|gzip|bzip|bzip2)$/;
|
2020-10-02 20:44:29 +08:00
|
|
|
|
|
|
|
switch (true) {
|
2021-02-22 22:16:33 +08:00
|
|
|
case 'image' == mimeTypeParts[0] || ['png', 'jpg', 'jpeg', 'gif', 'webp'].includes(ext):
|
2020-10-02 20:44:29 +08:00
|
|
|
result = FileType.Image;
|
|
|
|
break;
|
2021-02-22 22:16:33 +08:00
|
|
|
case 'audio' == mimeTypeParts[0] || ['mp3', 'ogg', 'oga', 'wav'].includes(ext):
|
2020-10-02 20:44:29 +08:00
|
|
|
result = FileType.Audio;
|
|
|
|
break;
|
2021-02-22 22:16:33 +08:00
|
|
|
case 'video' == mimeTypeParts[0] || 'mkv' == ext || 'avi' == ext:
|
2020-10-02 20:44:29 +08:00
|
|
|
result = FileType.Video;
|
|
|
|
break;
|
|
|
|
case ['php', 'js', 'css'].includes(ext):
|
|
|
|
result = FileType.Code;
|
|
|
|
break;
|
2021-02-22 22:16:33 +08:00
|
|
|
case 'eml' == ext || ['message/delivery-status', 'message/rfc822'].includes(mimeType):
|
2020-10-02 20:44:29 +08:00
|
|
|
result = FileType.Eml;
|
|
|
|
break;
|
2021-02-22 22:16:33 +08:00
|
|
|
case 'text/html' == mimeType || 'html' == ext:
|
2020-10-02 20:44:29 +08:00
|
|
|
result = FileType.Html;
|
|
|
|
break;
|
2021-02-22 22:16:33 +08:00
|
|
|
case 'text' == mimeTypeParts[0] || 'txt' == ext || 'log' == ext:
|
2020-10-02 20:44:29 +08:00
|
|
|
result = FileType.Text;
|
|
|
|
break;
|
2021-02-22 22:16:33 +08:00
|
|
|
case archive.test(type) || archive.test(ext):
|
2020-10-02 20:44:29 +08:00
|
|
|
result = FileType.Archive;
|
|
|
|
break;
|
2021-01-27 07:26:31 +08:00
|
|
|
case 'pdf' == type || 'pdf' == ext:
|
2020-10-02 20:44:29 +08:00
|
|
|
result = FileType.Pdf;
|
|
|
|
break;
|
2021-02-22 22:16:33 +08:00
|
|
|
case [app+'pgp-signature', app+'pgp-keys'].includes(mimeType) ||
|
2020-10-02 20:44:29 +08:00
|
|
|
['asc', 'pem', 'ppk'].includes(ext):
|
|
|
|
result = FileType.Certificate;
|
|
|
|
break;
|
2021-02-22 22:16:33 +08:00
|
|
|
case [app+'pkcs7-signature'].includes(mimeType) || 'p7s' == ext:
|
2020-10-02 20:44:29 +08:00
|
|
|
result = FileType.CertificateBin;
|
|
|
|
break;
|
|
|
|
case match(msOffice+'.wordprocessingml') || match(openDoc+'.text') || match('vnd.ms-word')
|
|
|
|
|| ['rtf', 'msword', 'vnd.msword'].includes(type):
|
|
|
|
result = FileType.WordText;
|
|
|
|
break;
|
|
|
|
case match(msOffice+'.spreadsheetml') || match(openDoc+'.spreadsheet') || match('ms-excel'):
|
|
|
|
result = FileType.Sheet;
|
|
|
|
break;
|
|
|
|
case match(msOffice+'.presentationml') || match(openDoc+'.presentation') || match('ms-powerpoint'):
|
|
|
|
result = FileType.Presentation;
|
|
|
|
break;
|
|
|
|
// no default
|
|
|
|
}
|
2021-02-22 22:16:33 +08:00
|
|
|
|
2020-10-02 20:44:29 +08:00
|
|
|
return cache[key] = result;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {string} sFileType
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
getTypeIconClass: fileType => {
|
|
|
|
let result = ['icon-file', ''];
|
|
|
|
switch (fileType) {
|
|
|
|
case FileType.Text:
|
|
|
|
case FileType.Eml:
|
|
|
|
case FileType.WordText:
|
|
|
|
result[0] += '-text';
|
|
|
|
break;
|
|
|
|
case FileType.Html:
|
|
|
|
case FileType.Code:
|
|
|
|
result[0] += '-code';
|
|
|
|
break;
|
|
|
|
case FileType.Image:
|
|
|
|
result[0] += '-image';
|
|
|
|
break;
|
|
|
|
case FileType.Audio:
|
|
|
|
result[0] += '-music';
|
|
|
|
break;
|
|
|
|
case FileType.Video:
|
|
|
|
result[0] += '-movie';
|
|
|
|
break;
|
|
|
|
case FileType.Archive:
|
|
|
|
result[0] += '-zip';
|
|
|
|
break;
|
|
|
|
case FileType.Certificate:
|
|
|
|
case FileType.CertificateBin:
|
|
|
|
result[0] += '-certificate';
|
|
|
|
break;
|
|
|
|
case FileType.Sheet:
|
|
|
|
result[0] += '-excel';
|
|
|
|
break;
|
|
|
|
case FileType.Presentation:
|
|
|
|
result[0] += '-chart-graph';
|
|
|
|
break;
|
|
|
|
case FileType.Pdf:
|
2021-04-12 19:20:18 +08:00
|
|
|
result[1] = 'pdf';
|
2020-10-02 20:44:29 +08:00
|
|
|
break;
|
|
|
|
// no default
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
|
2021-02-17 21:40:21 +08:00
|
|
|
getIconClass: (ext, mime) => FileInfo.getTypeIconClass(FileInfo.getType(ext, mime)),
|
2020-10-02 20:44:29 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {string} sFileType
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
getCombinedIconClass: data => {
|
2021-03-16 23:49:14 +08:00
|
|
|
if (isNonEmptyArray(data)) {
|
2020-10-02 20:44:29 +08:00
|
|
|
let icons = data
|
2021-02-17 21:40:21 +08:00
|
|
|
.map(item => item ? FileInfo.getIconClass(FileInfo.getExtension(item[0]), item[1])[0] : '')
|
2020-10-03 05:54:15 +08:00
|
|
|
.validUnique();
|
2020-10-02 20:44:29 +08:00
|
|
|
|
|
|
|
return (icons && 1 === icons.length && 'icon-file' !== icons[0])
|
|
|
|
? icons[0]
|
|
|
|
: 'icon-attachment';
|
|
|
|
}
|
|
|
|
|
|
|
|
return '';
|
2020-10-03 20:02:33 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
friendlySize: bytes => {
|
|
|
|
bytes = parseInt(bytes, 10) || 0;
|
|
|
|
let i = Math.floor(Math.log(bytes) / Math.log(1024));
|
2021-03-25 23:51:54 +08:00
|
|
|
return (bytes / Math.pow(1024, i)).toFixed(2>i ? 0 : 1) + ' ' + sizes[i];
|
2020-10-02 20:44:29 +08:00
|
|
|
}
|
2020-10-03 20:02:33 +08:00
|
|
|
|
2020-10-02 20:44:29 +08:00
|
|
|
};
|