- Resize/re-encode every uploaded image server-side (posts, avatars, stories, shop products/logo, chat messages) via a shared sharp-based optimizer — caps dimensions to what's actually displayed and re-compresses in place, cutting a typical raw camera photo by ~90% with no visible quality loss - Cap uploaded video resolution/bitrate (re-encode only when above 1280px/ ~2.5Mbps) alongside the existing faststart step; apply faststart+cap to story and chat videos too (previously stored completely raw) - Add long-lived Cache-Control to all /storage static routes so clients stop re-downloading unchanged media on every request - Add gzip/brotli compression for JSON API responses (feed/explore/chat) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
42 lines
1.3 KiB
JavaScript
42 lines
1.3 KiB
JavaScript
const fs = require('fs-extra')
|
|
const path = require('path')
|
|
const axios = require('axios')
|
|
const { optimizeImageFile } = require('./imageOptimize')
|
|
|
|
const EXT_BY_CONTENT_TYPE = {
|
|
'image/png': '.png',
|
|
'image/webp': '.webp',
|
|
'image/gif': '.gif',
|
|
'image/jpeg': '.jpg',
|
|
}
|
|
|
|
/**
|
|
* Downloads a remote image and stores it under storage/profiles, the same
|
|
* directory setProfileImageController.js already uses for avatar uploads.
|
|
* Returns the relative "/profiles/<file>" path expected on UserModel.profile_image.
|
|
*/
|
|
async function downloadImageToProfiles(url, baseName) {
|
|
const uploadDir = path.join(__dirname, '../storage/profiles')
|
|
if (!fs.existsSync(uploadDir)) {
|
|
fs.mkdirSync(uploadDir, { recursive: true })
|
|
}
|
|
|
|
const response = await axios.get(url, {
|
|
responseType: 'arraybuffer',
|
|
timeout: 10000,
|
|
})
|
|
|
|
const contentType = String(response.headers['content-type'] || '').split(';')[0].trim()
|
|
const ext = EXT_BY_CONTENT_TYPE[contentType] || '.jpg'
|
|
const safeBaseName = String(baseName || 'user').replace(/[^\w.\-]/g, '_')
|
|
const uniqueFileName = `${safeBaseName}-${Date.now()}${ext}`
|
|
const filePath = path.join(uploadDir, uniqueFileName)
|
|
|
|
await fs.writeFile(filePath, Buffer.from(response.data))
|
|
await optimizeImageFile(filePath, { maxDimension: 800 })
|
|
|
|
return `/profiles/${uniqueFileName}`
|
|
}
|
|
|
|
module.exports = { downloadImageToProfiles }
|