mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 15:34:13 +00:00 
			
		
		
		
	fix(backend/DriveService): convert WebP/AVIF to WebP (#10239)
* fix(backend/DriveService): convert transparent WebP/AVIF to PNG * webpにする その希望が複数ありましたので * Update packages/backend/src/core/DriveService.ts Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> * update test * webpはwebpublicにできる --------- Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> Co-authored-by: tamaina <tamaina@hotmail.co.jp>
This commit is contained in:
		
							parent
							
								
									e0b7633a7a
								
							
						
					
					
						commit
						3f53cbd8f6
					
				
					 8 changed files with 86 additions and 42 deletions
				
			
		| 
						 | 
					@ -299,7 +299,7 @@ export class DriveService {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			satisfyWebpublic = !!(
 | 
								satisfyWebpublic = !!(
 | 
				
			||||||
				type !== 'image/svg+xml' && type !== 'image/webp' && type !== 'image/avif' &&
 | 
									type !== 'image/svg+xml' && type !== 'image/avif' &&
 | 
				
			||||||
			!(metadata.exif ?? metadata.iptc ?? metadata.xmp ?? metadata.tifftagPhotoshop) &&
 | 
								!(metadata.exif ?? metadata.iptc ?? metadata.xmp ?? metadata.tifftagPhotoshop) &&
 | 
				
			||||||
			metadata.width && metadata.width <= 2048 &&
 | 
								metadata.width && metadata.width <= 2048 &&
 | 
				
			||||||
			metadata.height && metadata.height <= 2048
 | 
								metadata.height && metadata.height <= 2048
 | 
				
			||||||
| 
						 | 
					@ -319,11 +319,11 @@ export class DriveService {
 | 
				
			||||||
			this.registerLogger.info('creating web image');
 | 
								this.registerLogger.info('creating web image');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			try {
 | 
								try {
 | 
				
			||||||
				if (['image/jpeg', 'image/webp', 'image/avif'].includes(type)) {
 | 
									if (type === 'image/jpeg') {
 | 
				
			||||||
					webpublic = await this.imageProcessingService.convertSharpToJpeg(img, 2048, 2048);
 | 
										webpublic = await this.imageProcessingService.convertSharpToJpeg(img, 2048, 2048);
 | 
				
			||||||
				} else if (['image/png'].includes(type)) {
 | 
									} else if (['image/webp', 'image/avif'].includes(type)) {
 | 
				
			||||||
					webpublic = await this.imageProcessingService.convertSharpToPng(img, 2048, 2048);
 | 
										webpublic = await this.imageProcessingService.convertSharpToWebp(img, 2048, 2048);
 | 
				
			||||||
				} else if (['image/svg+xml'].includes(type)) {
 | 
									} else if (['image/png', 'image/svg+xml'].includes(type)) {
 | 
				
			||||||
					webpublic = await this.imageProcessingService.convertSharpToPng(img, 2048, 2048);
 | 
										webpublic = await this.imageProcessingService.convertSharpToPng(img, 2048, 2048);
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					this.registerLogger.debug('web image not created (not an required image)');
 | 
										this.registerLogger.debug('web image not created (not an required image)');
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -155,7 +155,7 @@ export class ApRendererService {
 | 
				
			||||||
	public renderDocument(file: DriveFile): IApDocument {
 | 
						public renderDocument(file: DriveFile): IApDocument {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
			type: 'Document',
 | 
								type: 'Document',
 | 
				
			||||||
			mediaType: file.type,
 | 
								mediaType: file.webpublicType ?? file.type,
 | 
				
			||||||
			url: this.driveFileEntityService.getPublicUrl(file),
 | 
								url: this.driveFileEntityService.getPublicUrl(file),
 | 
				
			||||||
			name: file.comment,
 | 
								name: file.comment,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ import * as assert from 'assert';
 | 
				
			||||||
// node-fetch only supports it's own Blob yet
 | 
					// node-fetch only supports it's own Blob yet
 | 
				
			||||||
// https://github.com/node-fetch/node-fetch/pull/1664
 | 
					// https://github.com/node-fetch/node-fetch/pull/1664
 | 
				
			||||||
import { Blob } from 'node-fetch';
 | 
					import { Blob } from 'node-fetch';
 | 
				
			||||||
import { startServer, signup, post, api, uploadFile } from '../utils.js';
 | 
					import { startServer, signup, post, api, uploadFile, simpleGet } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					import type { INestApplicationContext } from '@nestjs/common';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Endpoints', () => {
 | 
					describe('Endpoints', () => {
 | 
				
			||||||
| 
						 | 
					@ -439,6 +439,45 @@ describe('Endpoints', () => {
 | 
				
			||||||
			assert.strictEqual(res.body.name, 'image.svg');
 | 
								assert.strictEqual(res.body.name, 'image.svg');
 | 
				
			||||||
			assert.strictEqual(res.body.type, 'image/svg+xml');
 | 
								assert.strictEqual(res.body.type, 'image/svg+xml');
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (const type of ['webp', 'avif']) {
 | 
				
			||||||
 | 
								const mediaType = `image/${type}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								const getWebpublicType = async (user: any, fileId: string): Promise<string> => {
 | 
				
			||||||
 | 
									// drive/files/create does not expose webpublicType directly, so get it by posting it
 | 
				
			||||||
 | 
									const res = await post(user, {
 | 
				
			||||||
 | 
										text: mediaType,
 | 
				
			||||||
 | 
										fileIds: [fileId],
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
									const apRes = await simpleGet(`notes/${res.id}`, 'application/activity+json');
 | 
				
			||||||
 | 
									assert.strictEqual(apRes.status, 200);
 | 
				
			||||||
 | 
									assert.ok(Array.isArray(apRes.body.attachment));
 | 
				
			||||||
 | 
									return apRes.body.attachment[0].mediaType;
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								test(`透明な${type}ファイルを作成できる`, async () => {
 | 
				
			||||||
 | 
									const path = `with-alpha.${type}`;
 | 
				
			||||||
 | 
									const res = await uploadFile(alice, { path });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									assert.strictEqual(res.status, 200);
 | 
				
			||||||
 | 
									assert.strictEqual(res.body.name, path);
 | 
				
			||||||
 | 
									assert.strictEqual(res.body.type, mediaType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									const webpublicType = await getWebpublicType(alice, res.body.id);
 | 
				
			||||||
 | 
									assert.strictEqual(webpublicType, 'image/webp');
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								test(`透明じゃない${type}ファイルを作成できる`, async () => {
 | 
				
			||||||
 | 
									const path = `without-alpha.${type}`;
 | 
				
			||||||
 | 
									const res = await uploadFile(alice, { path });
 | 
				
			||||||
 | 
									assert.strictEqual(res.status, 200);
 | 
				
			||||||
 | 
									assert.strictEqual(res.body.name, path);
 | 
				
			||||||
 | 
									assert.strictEqual(res.body.type, mediaType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									const webpublicType = await getWebpublicType(alice, res.body.id);
 | 
				
			||||||
 | 
									assert.strictEqual(webpublicType, 'image/webp');
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	describe('drive/files/update', () => {
 | 
						describe('drive/files/update', () => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								packages/backend/test/resources/with-alpha.avif
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								packages/backend/test/resources/with-alpha.avif
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 9.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								packages/backend/test/resources/with-alpha.webp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								packages/backend/test/resources/with-alpha.webp
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 4.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								packages/backend/test/resources/without-alpha.avif
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								packages/backend/test/resources/without-alpha.avif
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 3.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								packages/backend/test/resources/without-alpha.webp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								packages/backend/test/resources/without-alpha.webp
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 4.4 KiB  | 
| 
						 | 
					@ -204,7 +204,12 @@ export const simpleGet = async (path: string, accept = '*/*'): Promise<{ status:
 | 
				
			||||||
		redirect: 'manual',
 | 
							redirect: 'manual',
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const body = res.headers.get('content-type') === 'application/json; charset=utf-8'
 | 
						const jsonTypes = [
 | 
				
			||||||
 | 
							'application/json; charset=utf-8',
 | 
				
			||||||
 | 
							'application/activity+json; charset=utf-8',
 | 
				
			||||||
 | 
						];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const body = jsonTypes.includes(res.headers.get('content-type') ?? '')
 | 
				
			||||||
		? await res.json()
 | 
							? await res.json()
 | 
				
			||||||
		: null;
 | 
							: null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue