1c0d4546f7
Closes: #9711 (please check this issue first) I cherry-picked two commits ([1](8ae9d2eaa8
), [2](ed51209172
)) from [Misskey](https://github.com/misskey-dev/misskey) and made a few changes. 「ライセンス」should be written as "License" in the following screenshots, but it has not yet been translated. It would be nice if we could include multiple lines of text, but I just ported what's been implemented so far in Misskey not to mess things up. This is my first pull request (aside from typo correction). Feel free to point out any issues! ![](https://cdn.discordapp.com/attachments/823878222897741868/1086372711841935440/2023-03-18_042011.png) ![](https://cdn.discordapp.com/attachments/823878222897741868/1086373178214981853/01.png) ![](https://cdn.discordapp.com/attachments/823878222897741868/1086373336709341246/2023-03-18_042629.png) Co-authored-by: syuilo <Syuilotan@yahoo.co.jp> Co-authored-by: naskya <m@naskya.net> Reviewed-on: https://codeberg.org/calckey/calckey/pulls/9719 Co-authored-by: naskya <naskya@noreply.codeberg.org> Co-committed-by: naskya <naskya@noreply.codeberg.org>
92 lines
2.5 KiB
TypeScript
92 lines
2.5 KiB
TypeScript
import type Bull from "bull";
|
|
import * as fs from "node:fs";
|
|
import unzipper from "unzipper";
|
|
|
|
import { queueLogger } from "../../logger.js";
|
|
import { createTempDir } from "@/misc/create-temp.js";
|
|
import { downloadUrl } from "@/misc/download-url.js";
|
|
import { DriveFiles, Emojis } from "@/models/index.js";
|
|
import type { DbUserImportJobData } from "@/queue/types.js";
|
|
import { addFile } from "@/services/drive/add-file.js";
|
|
import { genId } from "@/misc/gen-id.js";
|
|
import { db } from "@/db/postgre.js";
|
|
|
|
const logger = queueLogger.createSubLogger("import-custom-emojis");
|
|
|
|
// TODO: 名前衝突時の動作を選べるようにする
|
|
export async function importCustomEmojis(
|
|
job: Bull.Job<DbUserImportJobData>,
|
|
done: any,
|
|
): Promise<void> {
|
|
logger.info("Importing custom emojis ...");
|
|
|
|
const file = await DriveFiles.findOneBy({
|
|
id: job.data.fileId,
|
|
});
|
|
if (file == null) {
|
|
done();
|
|
return;
|
|
}
|
|
|
|
const [path, cleanup] = await createTempDir();
|
|
|
|
logger.info(`Temp dir is ${path}`);
|
|
|
|
const destPath = `${path}/emojis.zip`;
|
|
|
|
try {
|
|
fs.writeFileSync(destPath, "", "binary");
|
|
await downloadUrl(file.url, destPath);
|
|
} catch (e) {
|
|
// TODO: 何度か再試行
|
|
if (e instanceof Error || typeof e === "string") {
|
|
logger.error(e);
|
|
}
|
|
throw e;
|
|
}
|
|
|
|
const outputPath = `${path}/emojis`;
|
|
const unzipStream = fs.createReadStream(destPath);
|
|
const extractor = unzipper.Extract({ path: outputPath });
|
|
extractor.on("close", async () => {
|
|
const metaRaw = fs.readFileSync(`${outputPath}/meta.json`, "utf-8");
|
|
const meta = JSON.parse(metaRaw);
|
|
|
|
for (const record of meta.emojis) {
|
|
if (!record.downloaded) continue;
|
|
const emojiInfo = record.emoji;
|
|
const emojiPath = `${outputPath}/${record.fileName}`;
|
|
await Emojis.delete({
|
|
name: emojiInfo.name,
|
|
});
|
|
const driveFile = await addFile({
|
|
user: null,
|
|
path: emojiPath,
|
|
name: record.fileName,
|
|
force: true,
|
|
});
|
|
const emoji = await Emojis.insert({
|
|
id: genId(),
|
|
updatedAt: new Date(),
|
|
name: emojiInfo.name,
|
|
category: emojiInfo.category,
|
|
host: null,
|
|
aliases: emojiInfo.aliases,
|
|
originalUrl: driveFile.url,
|
|
publicUrl: driveFile.webpublicUrl ?? driveFile.url,
|
|
type: driveFile.webpublicType ?? driveFile.type,
|
|
license: emojiInfo.license,
|
|
}).then((x) => Emojis.findOneByOrFail(x.identifiers[0]));
|
|
}
|
|
|
|
await db.queryResultCache!.remove(["meta_emojis"]);
|
|
|
|
cleanup();
|
|
|
|
logger.succ("Imported");
|
|
done();
|
|
});
|
|
unzipStream.pipe(extractor);
|
|
logger.succ(`Unzipping to ${outputPath}`);
|
|
}
|