Skip to content

Instantly share code, notes, and snippets.

@anushshukla
Created October 18, 2020 10:15
Show Gist options
  • Select an option

  • Save anushshukla/767ac6cb87c0799631f608539e6504aa to your computer and use it in GitHub Desktop.

Select an option

Save anushshukla/767ac6cb87c0799631f608539e6504aa to your computer and use it in GitHub Desktop.
Filer Helper to detect mime via CLI
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