Created
October 18, 2020 10:15
-
-
Save anushshukla/767ac6cb87c0799631f608539e6504aa to your computer and use it in GitHub Desktop.
Filer Helper to detect mime via CLI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { exec as defaultExec } from 'child_process' | |
| import fs from 'fs' | |
| import util from 'util' | |
| import safePromise from './safe-promise' | |
| const exec = util.promisify(defaultExec) | |
| const detectFile = async (filePath: string): Promise<string> => { | |
| // mmmagic avoided due to https://github.com/mscdex/mmmagic/issues/141#issuecomment-570085390 | |
| // file-typ avoided due to https://github.com/sindresorhus/file-type#supported-file-types | |
| const fileCommand = `file --mime-type ${filePath} | grep -oh "[a-z]*/[a-z]*$"` | |
| const { stdout, stderr } = await exec(fileCommand) | |
| if (stderr) { | |
| throw stderr | |
| } | |
| return stdout.trim() | |
| } | |
| const getMimeFromExt = async ( | |
| fileExtension: string | |
| ): Promise<[string] | [null, string]> => { | |
| // https://github.com/jshttp/mime-types is a good alternate | |
| const mimeTypesFetchingCommand = `wget -qO- http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types | egrep -v ^# | awk '{ for (i=2; i<=NF; i++) {print $i" "$1}}' | sort | grep ${fileExtension} | grep -oh "[a-z]*/[a-z]*$"` | |
| // @ToDo cache the above data in redis and return that while asynchronously update the redis | |
| const { stdout, stderr } = await exec(mimeTypesFetchingCommand) | |
| if (stderr) { | |
| return [stderr] | |
| } | |
| const mime = String(stdout).trim() | |
| return [null, mime] | |
| } | |
| export const getFilesizeInBytes = (filePath: string): number => | |
| fs.statSync(filePath).size | |
| interface IFileHelper { | |
| detectedFileMime: string | |
| fileExtension: string | |
| fileFormat: string | |
| fileType: string | |
| mimeTypeFromExt?: string | |
| } | |
| export default async (filePath: string): Promise<IFileHelper> => { | |
| const [detectFileError, detectedFileMime] = await safePromise( | |
| detectFile(filePath) | |
| ) | |
| if (detectFileError) { | |
| throw detectFileError | |
| } | |
| if (!detectedFileMime) { | |
| throw new Error('file meme detection failed') | |
| } | |
| const mimeParts = String(detectedFileMime).split('/') | |
| const fileType = mimeParts[0] | |
| const fileFormat = mimeParts[1] | |
| const fileExtension = filePath | |
| .substring(filePath.lastIndexOf('.') + 1) | |
| .toLowerCase() | |
| const [mimeTypesFetchingError, mimeTypeFromExt] = await getMimeFromExt( | |
| fileExtension | |
| ) | |
| if (mimeTypesFetchingError) { | |
| throw mimeTypesFetchingError | |
| } | |
| return { | |
| detectedFileMime, | |
| fileExtension, | |
| fileFormat, | |
| fileType, | |
| mimeTypeFromExt, | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment