enhance: convert svg to png of custom emojis
This commit is contained in:
parent
43baafbebb
commit
eec7e6500e
|
@ -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"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -62,7 +62,8 @@ export async function populateEmoji(emojiName: string, noteUserHost: string | nu
|
||||||
if (emoji == null) return null;
|
if (emoji == null) return null;
|
||||||
|
|
||||||
const isLocal = emoji.host == 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 {
|
return {
|
||||||
name: emojiName,
|
name: emojiName,
|
||||||
|
@ -116,7 +117,7 @@ export async function prefetchEmojis(emojis: { name: string; host: string | null
|
||||||
}
|
}
|
||||||
const _emojis = emojisQuery.length > 0 ? await Emojis.find({
|
const _emojis = emojisQuery.length > 0 ? await Emojis.find({
|
||||||
where: emojisQuery,
|
where: emojisQuery,
|
||||||
select: ['name', 'host', 'url'],
|
select: ['name', 'host', 'originalUrl', 'publicUrl'],
|
||||||
}) : [];
|
}) : [];
|
||||||
for (const emoji of _emojis) {
|
for (const emoji of _emojis) {
|
||||||
cache.set(`${emoji.name} ${emoji.host}`, emoji);
|
cache.set(`${emoji.name} ${emoji.host}`, emoji);
|
||||||
|
|
|
@ -32,13 +32,19 @@ export class Emoji {
|
||||||
@Column('varchar', {
|
@Column('varchar', {
|
||||||
length: 512,
|
length: 512,
|
||||||
})
|
})
|
||||||
public url: string;
|
public originalUrl: string;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 512,
|
||||||
|
})
|
||||||
|
public publicUrl: string;
|
||||||
|
|
||||||
@Column('varchar', {
|
@Column('varchar', {
|
||||||
length: 512, nullable: true,
|
length: 512, nullable: true,
|
||||||
})
|
})
|
||||||
public uri: string | null;
|
public uri: string | null;
|
||||||
|
|
||||||
|
// publicUrlの方のtypeが入る
|
||||||
@Column('varchar', {
|
@Column('varchar', {
|
||||||
length: 64, nullable: true,
|
length: 64, nullable: true,
|
||||||
})
|
})
|
||||||
|
|
|
@ -15,7 +15,8 @@ export class EmojiRepository extends Repository<Emoji> {
|
||||||
name: emoji.name,
|
name: emoji.name,
|
||||||
category: emoji.category,
|
category: emoji.category,
|
||||||
host: emoji.host,
|
host: emoji.host,
|
||||||
url: emoji.url,
|
// || emoji.originalUrl してるのは後方互換性のため
|
||||||
|
url: emoji.publicUrl || emoji.originalUrl,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ export async function exportCustomEmojis(job: Bull.Job, done: () => void): Promi
|
||||||
let downloaded = false;
|
let downloaded = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await downloadUrl(emoji.url, emojiPath);
|
await downloadUrl(emoji.originalUrl, emojiPath);
|
||||||
downloaded = true;
|
downloaded = true;
|
||||||
} catch (e) { // TODO: 何度か再試行
|
} catch (e) { // TODO: 何度か再試行
|
||||||
logger.error(e);
|
logger.error(e);
|
||||||
|
|
|
@ -67,8 +67,9 @@ export async function importCustomEmojis(job: Bull.Job<DbUserImportJobData>, don
|
||||||
category: emojiInfo.category,
|
category: emojiInfo.category,
|
||||||
host: null,
|
host: null,
|
||||||
aliases: emojiInfo.aliases,
|
aliases: emojiInfo.aliases,
|
||||||
url: driveFile.url,
|
originalUrl: driveFile.url,
|
||||||
type: driveFile.type,
|
publicUrl: driveFile.webpublicUrl ?? driveFile.url,
|
||||||
|
type: driveFile.webpublicType ?? driveFile.type,
|
||||||
}).then(x => Emojis.findOneOrFail(x.identifiers[0]));
|
}).then(x => Emojis.findOneOrFail(x.identifiers[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -320,14 +320,15 @@ export async function extractEmojis(tags: IObject | IObject[], host: string): Pr
|
||||||
if ((tag.updated != null && exists.updatedAt == null)
|
if ((tag.updated != null && exists.updatedAt == null)
|
||||||
|| (tag.id != null && exists.uri == null)
|
|| (tag.id != null && exists.uri == null)
|
||||||
|| (tag.updated != null && exists.updatedAt != null && new Date(tag.updated) > exists.updatedAt)
|
|| (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({
|
await Emojis.update({
|
||||||
host,
|
host,
|
||||||
name,
|
name,
|
||||||
}, {
|
}, {
|
||||||
uri: tag.id,
|
uri: tag.id,
|
||||||
url: tag.icon!.url,
|
originalUrl: tag.icon!.url,
|
||||||
|
publicUrl: tag.icon!.url,
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -347,7 +348,8 @@ export async function extractEmojis(tags: IObject | IObject[], host: string): Pr
|
||||||
host,
|
host,
|
||||||
name,
|
name,
|
||||||
uri: tag.id,
|
uri: tag.id,
|
||||||
url: tag.icon!.url,
|
originalUrl: tag.icon!.url,
|
||||||
|
publicUrl: tag.icon!.url,
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
aliases: [],
|
aliases: [],
|
||||||
} as Partial<Emoji>).then(x => Emojis.findOneOrFail(x.identifiers[0]));
|
} as Partial<Emoji>).then(x => Emojis.findOneOrFail(x.identifiers[0]));
|
||||||
|
|
|
@ -9,6 +9,6 @@ export default (emoji: Emoji) => ({
|
||||||
icon: {
|
icon: {
|
||||||
type: 'Image',
|
type: 'Image',
|
||||||
mediaType: emoji.type || 'image/png',
|
mediaType: emoji.type || 'image/png',
|
||||||
url: emoji.url,
|
url: emoji.publicUrl || emoji.originalUrl, // || emoji.originalUrl してるのは後方互換性のため
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -45,8 +45,9 @@ export default define(meta, async (ps, me) => {
|
||||||
category: null,
|
category: null,
|
||||||
host: null,
|
host: null,
|
||||||
aliases: [],
|
aliases: [],
|
||||||
url: file.url,
|
originalUrl: file.url,
|
||||||
type: file.type,
|
publicUrl: file.webpublicUrl ?? file.url,
|
||||||
|
type: file.webpublicType ?? file.type,
|
||||||
}).then(x => Emojis.findOneOrFail(x.identifiers[0]));
|
}).then(x => Emojis.findOneOrFail(x.identifiers[0]));
|
||||||
|
|
||||||
await getConnection().queryResultCache!.remove(['meta_emojis']);
|
await getConnection().queryResultCache!.remove(['meta_emojis']);
|
||||||
|
|
|
@ -54,7 +54,7 @@ export default define(meta, async (ps, me) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Create file
|
// Create file
|
||||||
driveFile = await uploadFromUrl(emoji.url, null, null, null, false, true);
|
driveFile = await uploadFromUrl(emoji.originalUrl, null, null, null, false, true);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new ApiError();
|
throw new ApiError();
|
||||||
}
|
}
|
||||||
|
@ -65,9 +65,9 @@ export default define(meta, async (ps, me) => {
|
||||||
name: emoji.name,
|
name: emoji.name,
|
||||||
host: null,
|
host: null,
|
||||||
aliases: [],
|
aliases: [],
|
||||||
url: driveFile.url,
|
originalUrl: driveFile.url,
|
||||||
type: driveFile.type,
|
publicUrl: driveFile.webpublicUrl ?? driveFile.url,
|
||||||
fileId: driveFile.id,
|
type: driveFile.webpublicType ?? driveFile.type,
|
||||||
}).then(x => Emojis.findOneOrFail(x.identifiers[0]));
|
}).then(x => Emojis.findOneOrFail(x.identifiers[0]));
|
||||||
|
|
||||||
await getConnection().queryResultCache!.remove(['meta_emojis']);
|
await getConnection().queryResultCache!.remove(['meta_emojis']);
|
||||||
|
|
|
@ -81,19 +81,15 @@ export default async (user: { id: User['id']; host: User['host']; }, note: Note,
|
||||||
name: decodedReaction.name,
|
name: decodedReaction.name,
|
||||||
host: decodedReaction.host,
|
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', {
|
publishNoteStream(note.id, 'reacted', {
|
||||||
reaction: decodedReaction.reaction,
|
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,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
});
|
|
Loading…
Reference in New Issue