Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance: Fedibird形式の絵文字情報連合に対応 #604

Open
wants to merge 28 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG_YOJO.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

### General
- Feat: システムユーザーのファイル一覧を追加 [#595](https://github.com/yojo-art/cherrypick/pull/595)
- Enhance: Fedibird形式の絵文字情報連合に対応 [#604](https://github.com/yojo-art/cherrypick/pull/604)
- 以下の情報が対応ソフト間で連合されます
- キーワード
- コピー条件
- カテゴリ
- 製作者
- ライセンス
- 説明
- 使用に関しての説明

### Client
- Enhance: ノート詳細から前後のHTL/LTLを開く機能を追加 [#572](https://github.com/yojo-art/cherrypick/pull/572)
Expand Down
34 changes: 34 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12638,6 +12638,40 @@ export interface Locale extends ILocale {
*/
"private": string;
};
"_emoji": {
/**
* この絵文字のコピーは許可されていません
*/
"copyPermissionIsDeny": string;
/**
* ライセンスと使用に関しての情報を読んで同意できるならOkを選択してください
*/
"seeLicense": string;
/**
* 使用に関して
*/
"usageInfo": string;
/**
* 作成者
*/
"author": string;
/**
* コピーの許可
*/
"copyPermission": string;
/**
* 許可
*/
"allow": string;
/**
* 禁止
*/
"deny": string;
/**
* 条件付き
*/
"conditional": string;
};
}
declare const locales: {
[lang: string]: Locale;
Expand Down
10 changes: 10 additions & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3374,3 +3374,13 @@ _searchbility:
followersAndReacted: "フォロワーと反応した人"
reactedOnly: "反応した人"
private: "自分だけ"

_emoji:
copyPermissionIsDeny: "この絵文字のコピーは許可されていません"
seeLicense: "ライセンスと使用に関しての情報を読んで同意できるならOkを選択してください"
usageInfo: "使用に関して"
author: "作成者"
copyPermission: "コピーの許可"
allow: "許可"
deny: "禁止"
conditional: "条件付き"
22 changes: 22 additions & 0 deletions packages/backend/migration/1735299834220-EmojiInfoFederation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project, noridev and cherryPick-project, yojo-art team
* SPDX-License-Identifier: AGPL-3.0-only
*/

export class EmojiInfoFederation1735299834220 {
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "emoji" ADD "usageInfo" character varying(512)`);
await queryRunner.query(`ALTER TABLE "emoji" ADD "description" character varying(512)`);
await queryRunner.query(`ALTER TABLE "emoji" ADD "author" character varying(128)`);
await queryRunner.query(`CREATE TYPE "public"."emoji_copypermission_enum" AS ENUM('allow', 'deny', 'conditional', 'null')`);
await queryRunner.query(`ALTER TABLE "emoji" ADD "copyPermission" "public"."emoji_copypermission_enum"`);
}

async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "copyPermission"`);
await queryRunner.query(`DROP TYPE "public"."emoji_copypermission_enum"`);
await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "author"`);
await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "description"`);
await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "usageInfo"`);
}
}
17 changes: 17 additions & 0 deletions packages/backend/src/core/CustomEmojiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { query } from '@/misc/prelude/url.js';
import type { Serialized } from '@/types.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
import { DriveService } from '@/core/DriveService.js';
import { emojiCopyPermissions } from '@/types.js';

const parseEmojiStrRegexp = /^([-\w]+)(?:@([\w.-]+))?$/;

Expand Down Expand Up @@ -69,6 +70,10 @@ export class CustomEmojiService implements OnApplicationShutdown {
isSensitive: boolean;
localOnly: boolean;
roleIdsThatCanBeUsedThisEmojiAsReaction: MiRole['id'][];
copyPermission: 'allow' | 'deny' | 'conditional' | null,
usageInfo: string | null,
author: string | null,
description: string | null,
}, moderator?: MiUser): Promise<MiEmoji> {
// システムユーザーとして再アップロード
if (!data.driveFile.user?.isRoot) {
Expand All @@ -93,6 +98,10 @@ export class CustomEmojiService implements OnApplicationShutdown {
isSensitive: data.isSensitive,
localOnly: data.localOnly,
roleIdsThatCanBeUsedThisEmojiAsReaction: data.roleIdsThatCanBeUsedThisEmojiAsReaction,
copyPermission: data.copyPermission,
usageInfo: data.usageInfo,
author: data.author,
description: data.description,
});

if (data.host == null) {
Expand Down Expand Up @@ -127,6 +136,10 @@ export class CustomEmojiService implements OnApplicationShutdown {
isSensitive?: boolean;
localOnly?: boolean;
roleIdsThatCanBeUsedThisEmojiAsReaction?: MiRole['id'][];
copyPermission?: 'allow' | 'deny' | 'conditional' | null,
usageInfo?: string | null,
author?: string | null,
description?: string | null,
}, moderator?: MiUser): Promise<
null
| 'NO_SUCH_EMOJI'
Expand Down Expand Up @@ -157,6 +170,10 @@ export class CustomEmojiService implements OnApplicationShutdown {
publicUrl: data.driveFile != null ? (data.driveFile.webpublicUrl ?? data.driveFile.url) : undefined,
type: data.driveFile != null ? (data.driveFile.webpublicType ?? data.driveFile.type) : undefined,
roleIdsThatCanBeUsedThisEmojiAsReaction: data.roleIdsThatCanBeUsedThisEmojiAsReaction ?? undefined,
copyPermission: data.copyPermission,
usageInfo: data.usageInfo,
author: data.author,
description: data.description,
});

this.localEmojisCache.refresh();
Expand Down
7 changes: 7 additions & 0 deletions packages/backend/src/core/activitypub/ApRendererService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,13 @@ export class ApRendererService {
// || emoji.originalUrl してるのは後方互換性のため(publicUrlはstringなので??はだめ)
url: emoji.publicUrl || emoji.originalUrl,
},
keywords: emoji.aliases,
...(emoji.copyPermission === null ? { } : { copyPermission: emoji.copyPermission }),
kozakura913 marked this conversation as resolved.
Show resolved Hide resolved
...(emoji.category === null ? { } : { category: emoji.category }),
...(emoji.license === null ? { } : { license: emoji.license }),
...(emoji.usageInfo === null ? { } : { usageInfo: emoji.usageInfo }),
...(emoji.author === null ? { } : { author: emoji.author }),
...(emoji.description === null ? { } : { description: emoji.description }),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

送信絵文字全部に詳細まで付くんだ。
idやuriで参照とかじゃないのね。
先行実装がそうなんだよね?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これが飛んできてた
https://fedibird.com/emojis/92354.json

};
}

Expand Down
15 changes: 14 additions & 1 deletion packages/backend/src/core/activitypub/models/ApNoteService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,13 @@ export class ApNoteService {
originalUrl: tag.icon.url,
publicUrl: tag.icon.url,
updatedAt: new Date(),
aliases: tag.keywords,
copyPermission: tag.copyPermission,
category: tag.category,
author: tag.author,
license: tag.license,
description: tag.description,
usageInfo: tag.usageInfo,
});

const emoji = await this.emojisRepository.findOneBy({ host, name });
Expand All @@ -539,7 +546,13 @@ export class ApNoteService {
originalUrl: tag.icon.url,
publicUrl: tag.icon.url,
updatedAt: new Date(),
aliases: [],
aliases: tag.keywords,
copyPermission: tag.copyPermission,
category: tag.category,
author: tag.author,
license: tag.license,
description: tag.description,
usageInfo: tag.usageInfo,
});
}));
}
Expand Down
7 changes: 7 additions & 0 deletions packages/backend/src/core/activitypub/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,13 @@ export interface IApEmoji extends IObject {
type: 'Emoji';
name: string;
updated: string;
copyPermission?: 'allow' | 'deny' | 'conditional';
category?: string;
license?: string;
keywords?: string[];
usageInfo?: string;
author?: string;
description?: string;
}

export const isEmoji = (object: IObject): object is IApEmoji =>
Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/core/entities/EmojiEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ export class EmojiEntityService {
isSensitive: emoji.isSensitive,
localOnly: emoji.localOnly,
roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction,
copyPermission: emoji.copyPermission,
usageInfo: emoji.usageInfo,
author: emoji.author,
description: emoji.description,
};
}

Expand Down
29 changes: 29 additions & 0 deletions packages/backend/src/models/Emoji.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import { PrimaryColumn, Entity, Index, Column } from 'typeorm';
import { id } from './util/id.js';
import { emojiCopyPermissions } from "@/types.js";

@Entity('emoji')
@Index(['name', 'host'], { unique: true })
Expand Down Expand Up @@ -76,6 +77,34 @@ export class MiEmoji {
})
public isSensitive: boolean;

@Column('varchar', {
length: 512,
default: null,
nullable: true,
})
public usageInfo: string | null;

@Column('varchar', {
length: 512,
default: null,
nullable: true,
})
public description: string | null;

@Column('varchar', {
length: 128,
default: null,
nullable: true,
})
public author: string | null;

@Column('enum',
{
enum: emojiCopyPermissions,
nullable: true,
})
public copyPermission: typeof emojiCopyPermissions[number] | null;

// TODO: 定期ジョブで存在しなくなったロールIDを除去するようにする
@Column('varchar', {
array: true, length: 128, default: '{}',
Expand Down
6 changes: 6 additions & 0 deletions packages/backend/src/models/json-schema/emoji.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { emojiCopyPermissions } from '@/types.js';

export const packedEmojiSimpleSchema = {
type: 'object',
properties: {
Expand Down Expand Up @@ -102,5 +104,9 @@ export const packedEmojiDetailedSchema = {
format: 'id',
},
},
copyPermission: { type: 'string', enum: emojiCopyPermissions, nullable: true, },
usageInfo: { type: 'string', nullable: true, },
author: { type: 'string', nullable: true, },
description: { type: 'string', nullable: true, },
},
} as const;
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ export class ImportCustomEmojisProcessorService {
license: emojiInfo.license,
isSensitive: emojiInfo.isSensitive,
localOnly: emojiInfo.localOnly,
author: emojiInfo.author ?? null,
description: emojiInfo.description ?? null,
usageInfo: emojiInfo.usageInfo ?? null,
copyPermission: emojiInfo.copyPermission ?? null,
roleIdsThatCanBeUsedThisEmojiAsReaction: [],
});
} catch (e) {
Expand Down
10 changes: 10 additions & 0 deletions packages/backend/src/server/api/endpoints/admin/emoji/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { DriveFilesRepository } from '@/models/_.js';
import { DI } from '@/di-symbols.js';
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { emojiCopyPermissions } from '@/types.js';
import { ApiError } from '../../../error.js';

export const meta = {
Expand Down Expand Up @@ -56,6 +57,11 @@ export const paramDef = {
roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: {
type: 'string',
} },

copyPermission: { type: 'string', enum: emojiCopyPermissions, nullable: true, default: emojiCopyPermissions[0], description: 'この絵文字を外部サーバーへコピーすることの許可' },
usageInfo: { type: 'string', nullable: true, description: '使用する際の説明' },
author: { type: 'string', nullable: true, description: '作者情報' },
description: { type: 'string', nullable: true, description: '絵文字の説明' },
},
required: ['name', 'fileId'],
} as const;
Expand Down Expand Up @@ -88,6 +94,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
isSensitive: ps.isSensitive ?? false,
localOnly: ps.localOnly ?? false,
roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction ?? [],
copyPermission: ps.copyPermission ?? null,
usageInfo: ps.usageInfo ?? null,
author: ps.author ?? null,
description: ps.description ?? null,
}, me);

return this.emojiEntityService.packDetailed(emoji);
Expand Down
9 changes: 9 additions & 0 deletions packages/backend/src/server/api/endpoints/admin/emoji/adds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { secureRndstr } from '@/misc/secure-rndstr.js';
import { ApiError } from '../../../error.js';
import { emojiCopyPermissions } from '@/types.js';

export const meta = {
tags: ['admin'],
Expand Down Expand Up @@ -57,6 +58,10 @@ export const paramDef = {
roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: {
type: 'string',
} },
copyPermission: { type: 'string', enum: emojiCopyPermissions, nullable: true, default: emojiCopyPermissions[0], description: 'この絵文字を外部サーバーへコピーすることの許可' },
usageInfo: { type: 'string', nullable: true, description: '使用する際の説明' },
author: { type: 'string', nullable: true, description: '作者情報' },
description: { type: 'string', nullable: true, description: '絵文字の説明' },
},
required: ['fileId'],
} as const;
Expand Down Expand Up @@ -92,6 +97,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
isSensitive: ps.isSensitive ?? false,
localOnly: ps.localOnly ?? false,
roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction ?? [],
copyPermission: ps.copyPermission ?? null,
usageInfo: ps.usageInfo ?? null,
author: ps.author ?? null,
description: ps.description ?? null,
}, me);

return this.emojiEntityService.packDetailed(emoji);
Expand Down
Loading
Loading