From eec7e6500ed7f56a3b545adbb45420b3e1c7b0a9 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Fri, 21 Jan 2022 18:47:02 +0900
Subject: [PATCH] enhance: convert svg to png of custom emojis

---
 .../migration/1642611822809-emoji-url.js      | 15 +++++++++
 packages/backend/src/misc/populate-emojis.ts  |  5 +--
 packages/backend/src/models/entities/emoji.ts |  8 ++++-
 .../backend/src/models/repositories/emoji.ts  |  3 +-
 .../processors/db/export-custom-emojis.ts     |  2 +-
 .../processors/db/import-custom-emojis.ts     |  5 +--
 .../src/remote/activitypub/models/note.ts     |  8 +++--
 .../src/remote/activitypub/renderer/emoji.ts  |  2 +-
 .../server/api/endpoints/admin/emoji/add.ts   |  5 +--
 .../server/api/endpoints/admin/emoji/copy.ts  |  8 ++---
 .../src/services/note/reaction/create.ts      | 14 +++-----
 packages/backend/src/tools/add-emoji.ts       | 33 -------------------
 12 files changed, 49 insertions(+), 59 deletions(-)
 create mode 100644 packages/backend/migration/1642611822809-emoji-url.js
 delete mode 100644 packages/backend/src/tools/add-emoji.ts

diff --git a/packages/backend/migration/1642611822809-emoji-url.js b/packages/backend/migration/1642611822809-emoji-url.js
new file mode 100644
index 0000000000..f229c403f4
--- /dev/null
+++ b/packages/backend/migration/1642611822809-emoji-url.js
@@ -0,0 +1,15 @@
+const { MigrationInterface, QueryRunner } = require("typeorm");
+
+module.exports = class emojiUrl1642611822809 {
+		name = 'emojiUrl1642611822809'
+
+		async up(queryRunner) {
+			await queryRunner.query(`ALTER TABLE "emoji" RENAME COLUMN "url" TO "originalUrl"`);
+			await queryRunner.query(`ALTER TABLE "emoji" ADD "publicUrl" character varying(512) NOT NULL DEFAULT ''`);
+		}
+
+		async down(queryRunner) {
+			await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "publicUrl"`);
+			await queryRunner.query(`ALTER TABLE "emoji" RENAME COLUMN "originalUrl" TO "url"`);
+		}
+}
diff --git a/packages/backend/src/misc/populate-emojis.ts b/packages/backend/src/misc/populate-emojis.ts
index b021ec46eb..26c05e5fa6 100644
--- a/packages/backend/src/misc/populate-emojis.ts
+++ b/packages/backend/src/misc/populate-emojis.ts
@@ -62,7 +62,8 @@ export async function populateEmoji(emojiName: string, noteUserHost: string | nu
 	if (emoji == null) return null;
 
 	const isLocal = emoji.host == null;
-	const url = isLocal ? emoji.url : `${config.url}/proxy/image.png?${query({ url: emoji.url })}`;
+	const emojiUrl = emoji.publicUrl || emoji.originalUrl; // || emoji.originalUrl してるのは後方互換性のため
+	const url = isLocal ? emojiUrl : `${config.url}/proxy/image.png?${query({ url: emojiUrl })}`;
 
 	return {
 		name: emojiName,
@@ -116,7 +117,7 @@ export async function prefetchEmojis(emojis: { name: string; host: string | null
 	}
 	const _emojis = emojisQuery.length > 0 ? await Emojis.find({
 		where: emojisQuery,
-		select: ['name', 'host', 'url'],
+		select: ['name', 'host', 'originalUrl', 'publicUrl'],
 	}) : [];
 	for (const emoji of _emojis) {
 		cache.set(`${emoji.name} ${emoji.host}`, emoji);
diff --git a/packages/backend/src/models/entities/emoji.ts b/packages/backend/src/models/entities/emoji.ts
index 1146908a88..2e9c11d21c 100644
--- a/packages/backend/src/models/entities/emoji.ts
+++ b/packages/backend/src/models/entities/emoji.ts
@@ -32,13 +32,19 @@ export class Emoji {
 	@Column('varchar', {
 		length: 512,
 	})
-	public url: string;
+	public originalUrl: string;
+
+	@Column('varchar', {
+		length: 512,
+	})
+	public publicUrl: string;
 
 	@Column('varchar', {
 		length: 512, nullable: true,
 	})
 	public uri: string | null;
 
+	// publicUrlの方のtypeが入る
 	@Column('varchar', {
 		length: 64, nullable: true,
 	})
diff --git a/packages/backend/src/models/repositories/emoji.ts b/packages/backend/src/models/repositories/emoji.ts
index 9d63ced811..b9dc6ed0ac 100644
--- a/packages/backend/src/models/repositories/emoji.ts
+++ b/packages/backend/src/models/repositories/emoji.ts
@@ -15,7 +15,8 @@ export class EmojiRepository extends Repository<Emoji> {
 			name: emoji.name,
 			category: emoji.category,
 			host: emoji.host,
-			url: emoji.url,
+			// || emoji.originalUrl してるのは後方互換性のため
+			url: emoji.publicUrl || emoji.originalUrl,
 		};
 	}
 
diff --git a/packages/backend/src/queue/processors/db/export-custom-emojis.ts b/packages/backend/src/queue/processors/db/export-custom-emojis.ts
index 92344430d6..0c06b12c9a 100644
--- a/packages/backend/src/queue/processors/db/export-custom-emojis.ts
+++ b/packages/backend/src/queue/processors/db/export-custom-emojis.ts
@@ -72,7 +72,7 @@ export async function exportCustomEmojis(job: Bull.Job, done: () => void): Promi
 		let downloaded = false;
 
 		try {
-			await downloadUrl(emoji.url, emojiPath);
+			await downloadUrl(emoji.originalUrl, emojiPath);
 			downloaded = true;
 		} catch (e) { // TODO: 何度か再試行
 			logger.error(e);
diff --git a/packages/backend/src/queue/processors/db/import-custom-emojis.ts b/packages/backend/src/queue/processors/db/import-custom-emojis.ts
index ba4e3f0c08..d2b0eb269a 100644
--- a/packages/backend/src/queue/processors/db/import-custom-emojis.ts
+++ b/packages/backend/src/queue/processors/db/import-custom-emojis.ts
@@ -67,8 +67,9 @@ export async function importCustomEmojis(job: Bull.Job<DbUserImportJobData>, don
 				category: emojiInfo.category,
 				host: null,
 				aliases: emojiInfo.aliases,
-				url: driveFile.url,
-				type: driveFile.type,
+				originalUrl: driveFile.url,
+				publicUrl: driveFile.webpublicUrl ?? driveFile.url,
+				type: driveFile.webpublicType ?? driveFile.type,
 			}).then(x => Emojis.findOneOrFail(x.identifiers[0]));
 		}
 
diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts
index a0fdf7f239..6847925a51 100644
--- a/packages/backend/src/remote/activitypub/models/note.ts
+++ b/packages/backend/src/remote/activitypub/models/note.ts
@@ -320,14 +320,15 @@ export async function extractEmojis(tags: IObject | IObject[], host: string): Pr
 			if ((tag.updated != null && exists.updatedAt == null)
 				|| (tag.id != null && exists.uri == null)
 				|| (tag.updated != null && exists.updatedAt != null && new Date(tag.updated) > exists.updatedAt)
-				|| (tag.icon!.url !== exists.url)
+				|| (tag.icon!.url !== exists.originalUrl)
 			) {
 				await Emojis.update({
 					host,
 					name,
 				}, {
 					uri: tag.id,
-					url: tag.icon!.url,
+					originalUrl: tag.icon!.url,
+					publicUrl: tag.icon!.url,
 					updatedAt: new Date(),
 				});
 
@@ -347,7 +348,8 @@ export async function extractEmojis(tags: IObject | IObject[], host: string): Pr
 			host,
 			name,
 			uri: tag.id,
-			url: tag.icon!.url,
+			originalUrl: tag.icon!.url,
+			publicUrl: tag.icon!.url,
 			updatedAt: new Date(),
 			aliases: [],
 		} as Partial<Emoji>).then(x => Emojis.findOneOrFail(x.identifiers[0]));
diff --git a/packages/backend/src/remote/activitypub/renderer/emoji.ts b/packages/backend/src/remote/activitypub/renderer/emoji.ts
index 9d08c8ba81..e7ae7d959a 100644
--- a/packages/backend/src/remote/activitypub/renderer/emoji.ts
+++ b/packages/backend/src/remote/activitypub/renderer/emoji.ts
@@ -9,6 +9,6 @@ export default (emoji: Emoji) => ({
 	icon: {
 		type: 'Image',
 		mediaType: emoji.type || 'image/png',
-		url: emoji.url,
+		url: emoji.publicUrl || emoji.originalUrl, // || emoji.originalUrl してるのは後方互換性のため
 	},
 });
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts
index 72adda9dcb..1dfeae262f 100644
--- a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts
+++ b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts
@@ -45,8 +45,9 @@ export default define(meta, async (ps, me) => {
 		category: null,
 		host: null,
 		aliases: [],
-		url: file.url,
-		type: file.type,
+		originalUrl: file.url,
+		publicUrl: file.webpublicUrl ?? file.url,
+		type: file.webpublicType ?? file.type,
 	}).then(x => Emojis.findOneOrFail(x.identifiers[0]));
 
 	await getConnection().queryResultCache!.remove(['meta_emojis']);
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts b/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts
index de239c4f0d..4f53739793 100644
--- a/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts
+++ b/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts
@@ -54,7 +54,7 @@ export default define(meta, async (ps, me) => {
 
 	try {
 		// Create file
-		driveFile = await uploadFromUrl(emoji.url, null, null, null, false, true);
+		driveFile = await uploadFromUrl(emoji.originalUrl, null, null, null, false, true);
 	} catch (e) {
 		throw new ApiError();
 	}
@@ -65,9 +65,9 @@ export default define(meta, async (ps, me) => {
 		name: emoji.name,
 		host: null,
 		aliases: [],
-		url: driveFile.url,
-		type: driveFile.type,
-		fileId: driveFile.id,
+		originalUrl: driveFile.url,
+		publicUrl: driveFile.webpublicUrl ?? driveFile.url,
+		type: driveFile.webpublicType ?? driveFile.type,
 	}).then(x => Emojis.findOneOrFail(x.identifiers[0]));
 
 	await getConnection().queryResultCache!.remove(['meta_emojis']);
diff --git a/packages/backend/src/services/note/reaction/create.ts b/packages/backend/src/services/note/reaction/create.ts
index e0baa6a096..47f46419dd 100644
--- a/packages/backend/src/services/note/reaction/create.ts
+++ b/packages/backend/src/services/note/reaction/create.ts
@@ -81,19 +81,15 @@ export default async (user: { id: User['id']; host: User['host']; }, note: Note,
 			name: decodedReaction.name,
 			host: decodedReaction.host,
 		},
-		select: ['name', 'host', 'url'],
+		select: ['name', 'host', 'originalUrl', 'publicUrl'],
 	});
 
-	if (emoji) {
-		emoji = {
-			name: emoji.host ? `${emoji.name}@${emoji.host}` : `${emoji.name}@.`,
-			url: emoji.url,
-		} as any;
-	}
-
 	publishNoteStream(note.id, 'reacted', {
 		reaction: decodedReaction.reaction,
-		emoji: emoji,
+		emoji: emoji != null ? {
+			name: emoji.host ? `${emoji.name}@${emoji.host}` : `${emoji.name}@.`,
+			url: emoji.publicUrl || emoji.originalUrl, // || emoji.originalUrl してるのは後方互換性のため
+		} : null,
 		userId: user.id,
 	});
 
diff --git a/packages/backend/src/tools/add-emoji.ts b/packages/backend/src/tools/add-emoji.ts
deleted file mode 100644
index a3f4b54c7e..0000000000
--- a/packages/backend/src/tools/add-emoji.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { initDb } from '@/db/postgre';
-import { genId } from '@/misc/gen-id';
-
-async function main(name: string, url: string, alias?: string): Promise<any> {
-	await initDb();
-	const { Emojis } = await import('@/models/index');
-
-	const aliases = alias != null ? [ alias ] : [];
-
-	await Emojis.save({
-		id: genId(),
-		host: null,
-		name,
-		url,
-		aliases,
-		updatedAt: new Date(),
-	});
-}
-
-const args = process.argv.slice(2);
-const name = args[0];
-const url = args[1];
-
-if (!name) throw new Error('require name');
-if (!url) throw new Error('require url');
-
-main(name, url).then(() => {
-	console.log('success');
-	process.exit(0);
-}).catch(e => {
-	console.warn(e);
-	process.exit(1);
-});
-- 
GitLab