fix img upload from url, revert webp
This commit is contained in:
parent
f675ce7f93
commit
f6797e15a7
5 changed files with 77 additions and 99 deletions
|
@ -1,16 +1,14 @@
|
|||
<template>
|
||||
<figure :class='{ thumb, img: true }'
|
||||
<div :class='{ thumb, img: true }'
|
||||
:height="height" :width="width"
|
||||
:style="backgroundPreview">
|
||||
|
||||
<picture>
|
||||
<source :srcset="srcset" type='image/webp' />
|
||||
|
||||
<img
|
||||
v-if='media'
|
||||
:class='{ "u-featured": true, loading }'
|
||||
:alt='media.name' :loading='lazy?"lazy":"eager"'
|
||||
:src="src"
|
||||
:srcset="srcset"
|
||||
itemprop="image"
|
||||
:height="height" :width="width"
|
||||
:style="{ 'object-position': thumbnailPosition }"
|
||||
|
@ -18,10 +16,8 @@
|
|||
|
||||
<img v-else-if='!media && thumb' class='thumb' src="noimg.svg" alt=''>
|
||||
|
||||
</picture>
|
||||
|
||||
|
||||
</figure>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
|
@ -43,6 +39,10 @@ export default {
|
|||
backgroundImage: "url('data:image/png;base64," + this.media.preview + "')" }
|
||||
}
|
||||
},
|
||||
srcset () {
|
||||
if (this.thumb) return ''
|
||||
return `/media/thumb/${this.media.url} 500w, /media/${this.media.url} 1200w`
|
||||
},
|
||||
media () {
|
||||
return this.event.media[0]
|
||||
},
|
||||
|
@ -54,15 +54,12 @@ export default {
|
|||
},
|
||||
src () {
|
||||
if (this.media) {
|
||||
return '/media/' + (this.thumb ? 'thumb/' : '') + this.media.url
|
||||
return '/media/thumb/' + this.media.url
|
||||
}
|
||||
if (this.thumb) {
|
||||
return '/noimg.svg'
|
||||
}
|
||||
},
|
||||
srcset () {
|
||||
return this.src.replace(/.jpg$/, '.webp')
|
||||
},
|
||||
thumbnailPosition () {
|
||||
if (this.media.focalpoint) {
|
||||
const focalpoint = this.media.focalpoint
|
||||
|
@ -90,11 +87,12 @@ export default {
|
|||
}
|
||||
|
||||
.img img {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
transition: opacity 1s;
|
||||
transition: opacity .5s;
|
||||
opacity: 1;
|
||||
background-size: 100%;
|
||||
}
|
||||
|
@ -108,12 +106,7 @@ export default {
|
|||
aspect-ratio: 1.7778;
|
||||
}
|
||||
|
||||
.img picture {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.img picture img.loading {
|
||||
.img img.loading {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ const linkifyHtml = require('linkify-html')
|
|||
const Sequelize = require('sequelize')
|
||||
const dayjs = require('dayjs')
|
||||
const helpers = require('../../helpers')
|
||||
const settingsController = require('./settings')
|
||||
|
||||
const Event = require('../models/event')
|
||||
const Resource = require('../models/resource')
|
||||
|
@ -290,7 +289,7 @@ const eventController = {
|
|||
res.sendStatus(200)
|
||||
},
|
||||
|
||||
async isAnonEventAllowed (req, res, next) {
|
||||
async isAnonEventAllowed (_req, res, next) {
|
||||
if (!res.locals.settings.allow_anon_event) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
@ -317,7 +316,7 @@ const eventController = {
|
|||
|
||||
const eventDetails = {
|
||||
title: body.title,
|
||||
// remove html tags
|
||||
// sanitize and linkify html
|
||||
description: helpers.sanitizeHTML(linkifyHtml(body.description || '')),
|
||||
multidate: body.multidate,
|
||||
start_datetime: body.start_datetime,
|
||||
|
@ -328,17 +327,17 @@ const eventController = {
|
|||
}
|
||||
|
||||
if (req.file || body.image_url) {
|
||||
let url
|
||||
if (req.file) {
|
||||
url = req.file.filename
|
||||
} else {
|
||||
url = await helpers.getImageFromURL(body.image_url)
|
||||
if (body.image_url) {
|
||||
req.file = await helpers.getImageFromURL(body.image_url)
|
||||
}
|
||||
|
||||
let focalpoint = body.image_focalpoint ? body.image_focalpoint.split(',') : ['0', '0']
|
||||
focalpoint = [parseFloat(focalpoint[0]).toFixed(2), parseFloat(focalpoint[1]).toFixed(2)]
|
||||
eventDetails.media = [{
|
||||
url,
|
||||
url: req.file.filename,
|
||||
preview: req.file.preview,
|
||||
height: req.file.height,
|
||||
width: req.file.width,
|
||||
name: body.image_name || body.title || '',
|
||||
focalpoint: [parseFloat(focalpoint[0]), parseFloat(focalpoint[1])]
|
||||
}]
|
||||
|
@ -405,41 +404,39 @@ const eventController = {
|
|||
|
||||
const recurrent = body.recurrent ? JSON.parse(body.recurrent) : null
|
||||
const eventDetails = {
|
||||
title: body.title,
|
||||
// remove html tags
|
||||
description: helpers.sanitizeHTML(linkifyHtml(body.description, { target: '_blank' })),
|
||||
title: body.title || event.title,
|
||||
// sanitize and linkify html
|
||||
description: helpers.sanitizeHTML(linkifyHtml(body.description, { target: '_blank' })) || event.description,
|
||||
multidate: body.multidate,
|
||||
start_datetime: body.start_datetime,
|
||||
end_datetime: body.end_datetime,
|
||||
recurrent
|
||||
}
|
||||
|
||||
// remove old media in case a new one is uploaded
|
||||
if ((req.file || /^https?:\/\//.test(body.image_url)) && !event.recurrent && event.media && event.media.length) {
|
||||
const old_path = path.resolve(config.upload_path, event.media[0].url)
|
||||
const old_thumb_path = path.resolve(config.upload_path, 'thumb', event.media[0].url)
|
||||
try {
|
||||
const old_path = path.resolve(config.upload_path, event.media[0].url)
|
||||
const old_thumb_path = path.resolve(config.upload_path, 'thumb', event.media[0].url)
|
||||
fs.unlinkSync(old_path)
|
||||
fs.unlinkSync(old_thumb_path)
|
||||
} catch (e) {
|
||||
log.info(e.toString())
|
||||
}
|
||||
}
|
||||
let url
|
||||
if (req.file) {
|
||||
url = req.file.filename
|
||||
} else if (body.image_url) {
|
||||
if (/^https?:\/\//.test(body.image_url)) {
|
||||
url = await helpers.getImageFromURL(body.image_url)
|
||||
} else {
|
||||
url = body.image_url
|
||||
}
|
||||
}
|
||||
|
||||
if (url && !event.recurrent) {
|
||||
if (req.file || body.image_url) {
|
||||
if (body.image_url) {
|
||||
req.file = await helpers.getImageFromURL(body.image_url)
|
||||
}
|
||||
|
||||
const focalpoint = body.image_focalpoint ? body.image_focalpoint.split(',') : ['0', '0']
|
||||
eventDetails.media = [{
|
||||
url,
|
||||
name: body.image_name || '',
|
||||
url: req.file.filename,
|
||||
preview: req.file?.preview,
|
||||
height: req.file?.height,
|
||||
width: req.file?.width,
|
||||
name: body.image_name || body.title || '',
|
||||
focalpoint: [parseFloat(focalpoint[0].slice(0, 6)), parseFloat(focalpoint[1].slice(0, 6))]
|
||||
}]
|
||||
} else {
|
||||
|
@ -481,9 +478,9 @@ const eventController = {
|
|||
// check if event is mine (or user is admin)
|
||||
if (event && (res.locals.user.is_admin || res.locals.user.id === event.userId)) {
|
||||
if (event.media && event.media.length && !event.recurrent) {
|
||||
const old_path = path.join(config.upload_path, event.media[0].url)
|
||||
const old_thumb_path = path.join(config.upload_path, 'thumb', event.media[0].url)
|
||||
try {
|
||||
const old_path = path.join(config.upload_path, event.media[0].url)
|
||||
const old_thumb_path = path.join(config.upload_path, 'thumb', event.media[0].url)
|
||||
fs.unlinkSync(old_thumb_path)
|
||||
fs.unlinkSync(old_path)
|
||||
} catch (e) {
|
||||
|
|
|
@ -15,13 +15,11 @@ const DiskStorage = {
|
|||
const filename = crypto.randomBytes(16).toString('hex')
|
||||
const sharpStream = sharp({ failOnError: true })
|
||||
const promises = [
|
||||
sharpStream.clone().resize(500, null, { withoutEnlargement: true }).jpeg({ quality: 90, mozjpeg: true }).toFile(path.resolve(config.upload_path, 'thumb', filename + '.jpg')),
|
||||
sharpStream.clone().resize(500).webp({ quality: 90, alphaQuality: 0, effort: 6 }).toFile(path.resolve(config.upload_path, 'thumb', filename + '.webp')),
|
||||
sharpStream.clone().resize(1200, null, { withoutEnlargement: true } ).jpeg({ quality: 98, mozjpeg: true }).toFile(path.resolve(config.upload_path, filename + '.jpg')),
|
||||
sharpStream.clone().resize(1200).webp({ quality: 98, alphaQuality: 0, effor: 6 }).toFile(path.resolve(config.upload_path, filename + '.webp')),
|
||||
sharpStream.clone().resize(500, null, { withoutEnlargement: true }).jpeg({ effort: 6, mozjpeg: true }).toFile(path.resolve(config.upload_path, 'thumb', filename + '.jpg')),
|
||||
sharpStream.clone().resize(1200, null, { withoutEnlargement: true } ).jpeg({ quality: 95, effort: 6, mozjpeg: true}).toFile(path.resolve(config.upload_path, filename + '.jpg')),
|
||||
sharpStream.clone()
|
||||
.resize(6)
|
||||
.png({ quality: 20, palette: true, alphaQuality: 0, effort: 6})
|
||||
.resize(5)
|
||||
.png({ quality: 10, palette: true, effort: 6})
|
||||
.toBuffer()
|
||||
.then(buffer => buffer.toString('base64'))
|
||||
]
|
||||
|
@ -29,9 +27,8 @@ const DiskStorage = {
|
|||
file.stream.pipe(sharpStream)
|
||||
Promise.all(promises)
|
||||
.then(res => {
|
||||
const info = res[2]
|
||||
const preview = res[4]
|
||||
console.error(preview)
|
||||
const info = res[1]
|
||||
const preview = res[2]
|
||||
cb(null, {
|
||||
destination: config.upload_path,
|
||||
filename: filename + '.jpg',
|
||||
|
|
|
@ -7,7 +7,6 @@ const dayjs = require('dayjs')
|
|||
const config = require('./config')
|
||||
const log = require('./log')
|
||||
const pkg = require('../package.json')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const sharp = require('sharp')
|
||||
const axios = require('axios')
|
||||
|
@ -122,41 +121,41 @@ module.exports = {
|
|||
if(!/^https?:\/\//.test(url)) {
|
||||
throw Error('Hacking attempt?')
|
||||
}
|
||||
const filename = crypto.randomBytes(16).toString('hex') + '.jpg'
|
||||
const finalPath = path.resolve(config.upload_path, filename)
|
||||
const thumbPath = path.resolve(config.upload_path, 'thumb', filename)
|
||||
const outStream = fs.createWriteStream(finalPath)
|
||||
const thumbStream = fs.createWriteStream(thumbPath)
|
||||
|
||||
const resizer = sharp().resize(1200).jpeg({ quality: 95 })
|
||||
const thumbnailer = sharp().resize(400).jpeg({ quality: 90 })
|
||||
const filename = crypto.randomBytes(16).toString('hex')
|
||||
const sharpStream = sharp({ failOnError: true })
|
||||
const promises = [
|
||||
sharpStream.clone().resize(500, null, { withoutEnlargement: true }).jpeg({ effort: 6, mozjpeg: true }).toFile(path.resolve(config.upload_path, 'thumb', filename + '.jpg')),
|
||||
sharpStream.clone().resize(1200, null, { withoutEnlargement: true } ).jpeg({effort: 6, mozjpeg: true}).toFile(path.resolve(config.upload_path, filename + '.jpg')),
|
||||
sharpStream.clone()
|
||||
.resize(5)
|
||||
.png({ quality: 10, palette: true, effort: 6})
|
||||
.toBuffer()
|
||||
.then(buffer => buffer.toString('base64'))
|
||||
]
|
||||
|
||||
const response = await axios({ method: 'GET', url, responseType: 'stream' })
|
||||
const response = await axios({ method: 'GET', url: encodeURI(url), responseType: 'stream' })
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let onError = false
|
||||
const err = e => {
|
||||
if (onError) {
|
||||
return
|
||||
response.data.pipe(sharpStream)
|
||||
return Promise.all(promises)
|
||||
.then(res => {
|
||||
const info = res[1]
|
||||
const preview = res[2]
|
||||
return {
|
||||
destination: config.upload_path,
|
||||
filename: filename + '.jpg',
|
||||
path: path.resolve(config.upload_path, filename + '.jpg'),
|
||||
height: info.height,
|
||||
width: info.width,
|
||||
size: info.size,
|
||||
preview
|
||||
}
|
||||
onError = true
|
||||
reject(e)
|
||||
}
|
||||
|
||||
response.data
|
||||
.pipe(thumbnailer)
|
||||
.on('error', err)
|
||||
.pipe(thumbStream)
|
||||
.on('error', err)
|
||||
|
||||
response.data
|
||||
.pipe(resizer)
|
||||
.on('error', err)
|
||||
.pipe(outStream)
|
||||
.on('error', err)
|
||||
|
||||
outStream.on('finish', () => resolve(filename))
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
log.error(err)
|
||||
req.err = err
|
||||
cb(null)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,12 +32,8 @@
|
|||
})
|
||||
}
|
||||
|
||||
function thumbnail(event, format) {
|
||||
const imgPath = event.media[0].url
|
||||
if (format === 'webp') {
|
||||
return `${baseurl}/media/thumb/${imgPath.replace(/.jpg$/, '.webp')}`
|
||||
}
|
||||
return `${baseurl}/media/thumb/${imgPath}`
|
||||
function thumbnail(event) {
|
||||
return `${baseurl}/media/thumb/${event.media[0].url}`
|
||||
}
|
||||
|
||||
function position(event) {
|
||||
|
@ -53,11 +49,7 @@
|
|||
{#if event}
|
||||
<a href='{baseurl}/event/{event.slug || event.id}' class='card' target='_blank'>
|
||||
{#if event.media.length}
|
||||
|
||||
<picture>
|
||||
<source srcset="{thumbnail(event, 'webp')}" type='image/webp' />
|
||||
<img src="{thumbnail(event)}" alt="{event.media[0].name}" style="object-position: {position(event)}; aspect-ratio=1.7778;">
|
||||
</picture>
|
||||
<img src="{thumbnail(event)}" alt="{event.media[0].name}" style="object-position: {position(event)}; aspect-ratio=1.7778;">
|
||||
{/if}
|
||||
<div class="container">
|
||||
<strong>{event.title}</strong>
|
||||
|
|
Loading…
Reference in a new issue