parent
							
								
									85b7eb1fb8
								
							
						
					
					
						commit
						e37840d870
					
				
					 5 changed files with 37 additions and 29 deletions
				
			
		|  | @ -42,7 +42,7 @@ export default Vue.extend({ | |||
| 	}, | ||||
| 	methods: { | ||||
| 		previewable(file) { | ||||
| 			return file.type.startsWith('video') || file.type.startsWith('image'); | ||||
| 			return (file.type.startsWith('video') || file.type.startsWith('image')) && file.thumbnailUrl; | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ import { DriveFiles } from '../../models'; | |||
| import { InternalStorage } from '../../services/drive/internal-storage'; | ||||
| import { downloadUrl } from '../../misc/donwload-url'; | ||||
| import { detectMine } from '../../misc/detect-mine'; | ||||
| import { convertToJpeg, convertToPng, convertToGif, convertToApng } from '../../services/drive/image-processor'; | ||||
| import { convertToJpeg, convertToPng } from '../../services/drive/image-processor'; | ||||
| import { GenerateVideoThumbnail } from '../../services/drive/generate-video-thumbnail'; | ||||
| 
 | ||||
| const assets = `${__dirname}/../../server/file/assets/`; | ||||
|  | @ -60,10 +60,6 @@ export default async function(ctx: Koa.Context) { | |||
| 							return await convertToJpeg(path, 498, 280); | ||||
| 						} else if (['image/png'].includes(type)) { | ||||
| 							return await convertToPng(path, 498, 280); | ||||
| 						} else if (['image/gif'].includes(type)) { | ||||
| 							return await convertToGif(path); | ||||
| 						} else if (['image/apng', 'image/vnd.mozilla.apng'].includes(type)) { | ||||
| 							return await convertToApng(path); | ||||
| 						} else if (type.startsWith('video/')) { | ||||
| 							return await GenerateVideoThumbnail(path); | ||||
| 						} | ||||
|  | @ -101,22 +97,23 @@ export default async function(ctx: Koa.Context) { | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (isThumbnail) { | ||||
| 	if (isThumbnail || isWebpublic) { | ||||
| 		const [mime, ext] = await detectMine(InternalStorage.resolvePath(key)); | ||||
| 		const filename = rename(file.name, { | ||||
| 			suffix: isThumbnail ? '-thumb' : '-web', | ||||
| 			extname: ext ? `.${ext}` : undefined | ||||
| 		}).toString(); | ||||
| 
 | ||||
| 		ctx.body = InternalStorage.read(key); | ||||
| 		ctx.set('Content-Type', 'image/jpeg'); | ||||
| 		ctx.set('Content-Type', mime); | ||||
| 		ctx.set('Cache-Control', 'max-age=31536000, immutable'); | ||||
| 		ctx.set('Content-Disposition', contentDisposition('inline', `${rename(file.name, { suffix: '-thumb', extname: '.jpeg' })}`)); | ||||
| 	} else if (isWebpublic) { | ||||
| 		ctx.body = InternalStorage.read(key); | ||||
| 		ctx.set('Content-Type', file.type === 'image/apng' ? 'image/png' : file.type); | ||||
| 		ctx.set('Cache-Control', 'max-age=31536000, immutable'); | ||||
| 		ctx.set('Content-Disposition', contentDisposition('inline', `${rename(file.name, { suffix: '-web' })}`)); | ||||
| 		ctx.set('Content-Disposition', contentDisposition('inline', filename)); | ||||
| 	} else { | ||||
| 		const readable = InternalStorage.read(file.accessKey!); | ||||
| 		readable.on('error', commonReadableHandlerGenerator(ctx)); | ||||
| 		ctx.body = readable; | ||||
| 		ctx.set('Content-Type', file.type); | ||||
| 		ctx.set('Cache-Control', 'max-age=31536000, immutable'); | ||||
| 		ctx.set('Content-Disposition', contentDisposition('inline', `${file.name}`)); | ||||
| 		ctx.set('Content-Disposition', contentDisposition('inline', file.name)); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -159,6 +159,8 @@ export async function generateAlts(path: string, type: string, generateWeb: bool | |||
| 				webpublic = await convertToWebp(path, 2048, 2048); | ||||
| 			} else if (['image/png'].includes(type)) { | ||||
| 				webpublic = await convertToPng(path, 2048, 2048); | ||||
| 			} else { | ||||
| 				logger.debug(`web image not created (not an required image)`); | ||||
| 			} | ||||
| 		} catch (e) { | ||||
| 			logger.warn(`web image not created (an error occured)`, e); | ||||
|  | @ -180,8 +182,10 @@ export async function generateAlts(path: string, type: string, generateWeb: bool | |||
| 			try { | ||||
| 				thumbnail = await GenerateVideoThumbnail(path); | ||||
| 			} catch (e) { | ||||
| 				logger.error(`GenerateVideoThumbnail failed: ${e}`); | ||||
| 				logger.warn(`GenerateVideoThumbnail failed: ${e}`); | ||||
| 			} | ||||
| 		} else { | ||||
| 			logger.debug(`thumbnail not created (not an required file)`); | ||||
| 		} | ||||
| 	} catch (e) { | ||||
| 		logger.warn(`thumbnail not created (an error occured)`, e); | ||||
|  | @ -351,7 +355,7 @@ export default async function( | |||
| 
 | ||||
| 	let propPromises: Promise<void>[] = []; | ||||
| 
 | ||||
| 	const isImage = ['image/jpeg', 'image/gif', 'image/png', 'image/apng', 'image/vnd.mozilla.apng', 'image/webp'].includes(mime); | ||||
| 	const isImage = ['image/jpeg', 'image/gif', 'image/png', 'image/apng', 'image/vnd.mozilla.apng', 'image/webp', 'image/svg+xml'].includes(mime); | ||||
| 
 | ||||
| 	if (isImage) { | ||||
| 		const img = sharp(path); | ||||
|  | @ -374,15 +378,21 @@ export default async function( | |||
| 			logger.debug('calculating average color...'); | ||||
| 
 | ||||
| 			try { | ||||
| 				const info = await (img as any).stats(); | ||||
| 				const info = await img.stats(); | ||||
| 
 | ||||
| 				const r = Math.round(info.channels[0].mean); | ||||
| 				const g = Math.round(info.channels[1].mean); | ||||
| 				const b = Math.round(info.channels[2].mean); | ||||
| 				if (info.isOpaque) { | ||||
| 					const r = Math.round(info.channels[0].mean); | ||||
| 					const g = Math.round(info.channels[1].mean); | ||||
| 					const b = Math.round(info.channels[2].mean); | ||||
| 
 | ||||
| 				logger.debug(`average color is calculated: ${r}, ${g}, ${b}`); | ||||
| 					logger.debug(`average color is calculated: ${r}, ${g}, ${b}`); | ||||
| 
 | ||||
| 				properties['avgColor'] = `rgb(${r},${g},${b})`; | ||||
| 					properties['avgColor'] = `rgb(${r},${g},${b})`; | ||||
| 				} else { | ||||
| 					logger.debug(`this image is not opaque so average color is 255, 255, 255`); | ||||
| 
 | ||||
| 					properties['avgColor'] = `rgb(255,255,255)`; | ||||
| 				} | ||||
| 			} catch (e) { } | ||||
| 		}; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| import * as sharp from 'sharp'; | ||||
| import * as fs from 'fs'; | ||||
| 
 | ||||
| export type IImage = { | ||||
| 	data: Buffer; | ||||
|  |  | |||
|  | @ -3,25 +3,27 @@ import * as Path from 'path'; | |||
| import config from '../../config'; | ||||
| 
 | ||||
| export class InternalStorage { | ||||
| 	private static readonly path = Path.resolve(`${__dirname}/../../../files`); | ||||
| 	private static readonly path = Path.resolve(__dirname, '../../../files'); | ||||
| 
 | ||||
| 	public static resolvePath = (key: string) => Path.resolve(InternalStorage.path, key); | ||||
| 
 | ||||
| 	public static read(key: string) { | ||||
| 		return fs.createReadStream(`${InternalStorage.path}/${key}`); | ||||
| 		return fs.createReadStream(InternalStorage.resolvePath(key)); | ||||
| 	} | ||||
| 
 | ||||
| 	public static saveFromPath(key: string, srcPath: string) { | ||||
| 		fs.mkdirSync(InternalStorage.path, { recursive: true }); | ||||
| 		fs.copyFileSync(srcPath, `${InternalStorage.path}/${key}`); | ||||
| 		fs.copyFileSync(srcPath, InternalStorage.resolvePath(key)); | ||||
| 		return `${config.url}/files/${key}`; | ||||
| 	} | ||||
| 
 | ||||
| 	public static saveFromBuffer(key: string, data: Buffer) { | ||||
| 		fs.mkdirSync(InternalStorage.path, { recursive: true }); | ||||
| 		fs.writeFileSync(`${InternalStorage.path}/${key}`, data); | ||||
| 		fs.writeFileSync(InternalStorage.resolvePath(key), data); | ||||
| 		return `${config.url}/files/${key}`; | ||||
| 	} | ||||
| 
 | ||||
| 	public static del(key: string) { | ||||
| 		fs.unlink(`${InternalStorage.path}/${key}`, () => {}); | ||||
| 		fs.unlink(InternalStorage.resolvePath(key), () => {}); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue