You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.4 KiB
99 lines
2.4 KiB
const path = require('path')
|
|
const fs = require('fs')
|
|
const sharp = require('sharp')
|
|
const mkdirp = require('mkdirp')
|
|
const crypto = require('crypto')
|
|
const slugify = require('slugify')
|
|
|
|
const configStore = require('./../config.js')
|
|
|
|
/**
|
|
*
|
|
*
|
|
*/
|
|
class Media {
|
|
|
|
constructor() {
|
|
this._DIR_ASSETS = '/assets/'
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {string} src
|
|
* @param {object} sizes
|
|
* @param {Object} [options={}]
|
|
* @return {string}
|
|
*
|
|
*/
|
|
async resize(src, sizes, options = {}) {
|
|
|
|
this._extension = path.extname(src)
|
|
this._filename = slugify(path.basename(src, this._extension))
|
|
|
|
this._process = await sharp(configStore.get('source') + '/' + src)
|
|
|
|
// resize without options and with options
|
|
if (Object.getOwnPropertyNames(options).length === 0) {
|
|
await this._process
|
|
.resize(sizes)
|
|
} else {
|
|
this._process
|
|
.resize(sizes, options)
|
|
}
|
|
|
|
// optimize
|
|
this._optimize()
|
|
|
|
const fileBuffer = await this._process
|
|
.toBuffer()
|
|
|
|
const relativeDestinationPath = this._DIR_ASSETS + this._resolveRelativeDestinationPath(fileBuffer)
|
|
|
|
// create directories and write file
|
|
mkdirp.sync(configStore.get('destination') + relativeDestinationPath)
|
|
fs.writeFileSync(configStore.get('destination') + relativeDestinationPath + '/' + this._filename + this._extension, fileBuffer)
|
|
|
|
return relativeDestinationPath + '/' + this._filename + this._extension
|
|
}
|
|
|
|
/**
|
|
* @TODO much nicer to add a hook system so behavior can be change
|
|
*
|
|
*
|
|
* @param {string} extension
|
|
*
|
|
*/
|
|
_optimize() {
|
|
if (this._extension === '.gif') {
|
|
this._process
|
|
.gif({
|
|
reoptimise: true
|
|
})
|
|
} else {
|
|
|
|
// change extension
|
|
this._extension = '.webp'
|
|
this._process
|
|
.webp({
|
|
lossless: true
|
|
})
|
|
}
|
|
}
|
|
|
|
/**
|
|
* resolve path to write file, hash will be get = fileBuffer and
|
|
*
|
|
*
|
|
* @param {object} fileBuffer
|
|
* @return {string}
|
|
*
|
|
*/
|
|
_resolveRelativeDestinationPath(fileBuffer) {
|
|
const hash = crypto.createHash('sha1')
|
|
hash.update(fileBuffer)
|
|
|
|
return hash.digest('hex').match(new RegExp('.{1,8}', 'g')).join('/')
|
|
}
|
|
}
|
|
|
|
module.exports = Media |