feat: 投稿したコンテンツのAIによる学習を軽減するオプションを追加

Resolve #10819
This commit is contained in:
syuilo 2023-05-10 10:52:41 +09:00
parent baa45859c1
commit ae5a72a2df
16 changed files with 61 additions and 2 deletions

View File

@ -12,6 +12,17 @@
--> -->
## 13.x.x (unreleased)
### General
- 投稿したコンテンツのAIによる学習を軽減するオプションを追加
### Client
-
### Server
-
## 13.12.1 ## 13.12.1
### Client ### Client

View File

@ -1038,6 +1038,8 @@ thisChannelArchived: "このチャンネルはアーカイブされています
displayOfNote: "ノートの表示" displayOfNote: "ノートの表示"
initialAccountSetting: "初期設定" initialAccountSetting: "初期設定"
youFollowing: "フォロー中" youFollowing: "フォロー中"
preventAiLarning: "AIによる学習を防止"
preventAiLarningDescription: "投稿したート、添付した画像などのコンテンツを学習の対象にしないようAIに要求します。これはnoaiフラグをHTMLレスポンスに含めることによって実現されます。"
_initialAccountSetting: _initialAccountSetting:
accountCreated: "アカウントの作成が完了しました!" accountCreated: "アカウントの作成が完了しました!"

View File

@ -0,0 +1,11 @@
export class PreventAiLarning1683682889948 {
name = 'PreventAiLarning1683682889948'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "user_profile" ADD "preventAiLarning" boolean NOT NULL DEFAULT true`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "preventAiLarning"`);
}
}

View File

@ -445,6 +445,7 @@ export class UserEntityService implements OnModuleInit {
carefulBot: profile!.carefulBot, carefulBot: profile!.carefulBot,
autoAcceptFollowed: profile!.autoAcceptFollowed, autoAcceptFollowed: profile!.autoAcceptFollowed,
noCrawle: profile!.noCrawle, noCrawle: profile!.noCrawle,
preventAiLarning: profile!.preventAiLarning,
isExplorable: user.isExplorable, isExplorable: user.isExplorable,
isDeleted: user.isDeleted, isDeleted: user.isDeleted,
hideOnlineStatus: user.hideOnlineStatus, hideOnlineStatus: user.hideOnlineStatus,

View File

@ -147,6 +147,11 @@ export class UserProfile {
}) })
public noCrawle: boolean; public noCrawle: boolean;
@Column('boolean', {
default: true,
})
public preventAiLarning: boolean;
@Column('boolean', { @Column('boolean', {
default: false, default: false,
}) })

View File

@ -302,7 +302,11 @@ export const packedMeDetailedOnlySchema = {
}, },
noCrawle: { noCrawle: {
type: 'boolean', type: 'boolean',
nullable: true, optional: false, nullable: false, optional: false,
},
preventAiLarning: {
type: 'boolean',
nullable: false, optional: false,
}, },
isExplorable: { isExplorable: {
type: 'boolean', type: 'boolean',

View File

@ -68,6 +68,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
emailVerified: profile.emailVerified, emailVerified: profile.emailVerified,
autoAcceptFollowed: profile.autoAcceptFollowed, autoAcceptFollowed: profile.autoAcceptFollowed,
noCrawle: profile.noCrawle, noCrawle: profile.noCrawle,
preventAiLarning: profile.preventAiLarning,
alwaysMarkNsfw: profile.alwaysMarkNsfw, alwaysMarkNsfw: profile.alwaysMarkNsfw,
autoSensitive: profile.autoSensitive, autoSensitive: profile.autoSensitive,
carefulBot: profile.carefulBot, carefulBot: profile.carefulBot,

View File

@ -98,7 +98,7 @@ export const meta = {
message: 'This feature is restricted by your role.', message: 'This feature is restricted by your role.',
code: 'RESTRICTED_BY_ROLE', code: 'RESTRICTED_BY_ROLE',
id: '8feff0ba-5ab5-585b-31f4-4df816663fad', id: '8feff0ba-5ab5-585b-31f4-4df816663fad',
} },
}, },
res: { res: {
@ -138,6 +138,7 @@ export const paramDef = {
carefulBot: { type: 'boolean' }, carefulBot: { type: 'boolean' },
autoAcceptFollowed: { type: 'boolean' }, autoAcceptFollowed: { type: 'boolean' },
noCrawle: { type: 'boolean' }, noCrawle: { type: 'boolean' },
preventAiLarning: { type: 'boolean' },
isBot: { type: 'boolean' }, isBot: { type: 'boolean' },
isCat: { type: 'boolean' }, isCat: { type: 'boolean' },
showTimelineReplies: { type: 'boolean' }, showTimelineReplies: { type: 'boolean' },
@ -242,6 +243,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot; if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot;
if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed; if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed;
if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle; if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle;
if (typeof ps.preventAiLarning === 'boolean') profileUpdates.preventAiLarning = ps.preventAiLarning;
if (typeof ps.isCat === 'boolean') updates.isCat = ps.isCat; if (typeof ps.isCat === 'boolean') updates.isCat = ps.isCat;
if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote; if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote;
if (typeof ps.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail; if (typeof ps.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail;

View File

@ -21,6 +21,8 @@ block og
block meta block meta
if profile.noCrawle if profile.noCrawle
meta(name='robots' content='noindex') meta(name='robots' content='noindex')
if profile.preventAiLarning
meta(name='robots' content='noai')
meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-username' content=user.username)
meta(name='misskey:user-id' content=user.id) meta(name='misskey:user-id' content=user.id)

View File

@ -21,6 +21,8 @@ block og
block meta block meta
if profile.noCrawle if profile.noCrawle
meta(name='robots' content='noindex') meta(name='robots' content='noindex')
if profile.preventAiLarning
meta(name='robots' content='noai')
meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-username' content=user.username)
meta(name='misskey:user-id' content=user.id) meta(name='misskey:user-id' content=user.id)

View File

@ -21,6 +21,8 @@ block og
block meta block meta
if user.host || profile.noCrawle if user.host || profile.noCrawle
meta(name='robots' content='noindex') meta(name='robots' content='noindex')
if profile.preventAiLarning
meta(name='robots' content='noai')
meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-username' content=user.username)
meta(name='misskey:user-id' content=user.id) meta(name='misskey:user-id' content=user.id)

View File

@ -22,6 +22,8 @@ block og
block meta block meta
if user.host || isRenote || profile.noCrawle if user.host || isRenote || profile.noCrawle
meta(name='robots' content='noindex') meta(name='robots' content='noindex')
if profile.preventAiLarning
meta(name='robots' content='noai')
meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-username' content=user.username)
meta(name='misskey:user-id' content=user.id) meta(name='misskey:user-id' content=user.id)

View File

@ -21,6 +21,8 @@ block og
block meta block meta
if profile.noCrawle if profile.noCrawle
meta(name='robots' content='noindex') meta(name='robots' content='noindex')
if profile.preventAiLarning
meta(name='robots' content='noai')
meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-username' content=user.username)
meta(name='misskey:user-id' content=user.id) meta(name='misskey:user-id' content=user.id)

View File

@ -20,6 +20,8 @@ block og
block meta block meta
if user.host || profile.noCrawle if user.host || profile.noCrawle
meta(name='robots' content='noindex') meta(name='robots' content='noindex')
if profile.preventAiLarning
meta(name='robots' content='noai')
meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-username' content=user.username)
meta(name='misskey:user-id' content=user.id) meta(name='misskey:user-id' content=user.id)

View File

@ -145,6 +145,7 @@ describe('ユーザー', () => {
carefulBot: user.carefulBot, carefulBot: user.carefulBot,
autoAcceptFollowed: user.autoAcceptFollowed, autoAcceptFollowed: user.autoAcceptFollowed,
noCrawle: user.noCrawle, noCrawle: user.noCrawle,
preventAiLarning: user.preventAiLarning,
isExplorable: user.isExplorable, isExplorable: user.isExplorable,
isDeleted: user.isDeleted, isDeleted: user.isDeleted,
hideOnlineStatus: user.hideOnlineStatus, hideOnlineStatus: user.hideOnlineStatus,
@ -390,6 +391,7 @@ describe('ユーザー', () => {
assert.strictEqual(response.carefulBot, false); assert.strictEqual(response.carefulBot, false);
assert.strictEqual(response.autoAcceptFollowed, true); assert.strictEqual(response.autoAcceptFollowed, true);
assert.strictEqual(response.noCrawle, false); assert.strictEqual(response.noCrawle, false);
assert.strictEqual(response.preventAiLarning, true);
assert.strictEqual(response.isExplorable, true); assert.strictEqual(response.isExplorable, true);
assert.strictEqual(response.isDeleted, false); assert.strictEqual(response.isDeleted, false);
assert.strictEqual(response.hideOnlineStatus, false); assert.strictEqual(response.hideOnlineStatus, false);
@ -462,6 +464,8 @@ describe('ユーザー', () => {
{ parameters: (): object => ({ autoAcceptFollowed: false }) }, { parameters: (): object => ({ autoAcceptFollowed: false }) },
{ parameters: (): object => ({ noCrawle: true }) }, { parameters: (): object => ({ noCrawle: true }) },
{ parameters: (): object => ({ noCrawle: false }) }, { parameters: (): object => ({ noCrawle: false }) },
{ parameters: (): object => ({ preventAiLarning: false }) },
{ parameters: (): object => ({ preventAiLarning: true }) },
{ parameters: (): object => ({ isBot: true }) }, { parameters: (): object => ({ isBot: true }) },
{ parameters: (): object => ({ isBot: false }) }, { parameters: (): object => ({ isBot: false }) },
{ parameters: (): object => ({ isCat: true }) }, { parameters: (): object => ({ isCat: true }) },

View File

@ -24,6 +24,10 @@
{{ i18n.ts.noCrawle }} {{ i18n.ts.noCrawle }}
<template #caption>{{ i18n.ts.noCrawleDescription }}</template> <template #caption>{{ i18n.ts.noCrawleDescription }}</template>
</MkSwitch> </MkSwitch>
<MkSwitch v-model="preventAiLarning" @update:model-value="save()">
{{ i18n.ts.preventAiLarning }}<span class="_beta">{{ i18n.ts.beta }}</span>
<template #caption>{{ i18n.ts.preventAiLarningDescription }}</template>
</MkSwitch>
<MkSwitch v-model="isExplorable" @update:model-value="save()"> <MkSwitch v-model="isExplorable" @update:model-value="save()">
{{ i18n.ts.makeExplorable }} {{ i18n.ts.makeExplorable }}
<template #caption>{{ i18n.ts.makeExplorableDescription }}</template> <template #caption>{{ i18n.ts.makeExplorableDescription }}</template>
@ -71,6 +75,7 @@ import { definePageMetadata } from '@/scripts/page-metadata';
let isLocked = $ref($i.isLocked); let isLocked = $ref($i.isLocked);
let autoAcceptFollowed = $ref($i.autoAcceptFollowed); let autoAcceptFollowed = $ref($i.autoAcceptFollowed);
let noCrawle = $ref($i.noCrawle); let noCrawle = $ref($i.noCrawle);
let preventAiLarning = $ref($i.preventAiLarning);
let isExplorable = $ref($i.isExplorable); let isExplorable = $ref($i.isExplorable);
let hideOnlineStatus = $ref($i.hideOnlineStatus); let hideOnlineStatus = $ref($i.hideOnlineStatus);
let publicReactions = $ref($i.publicReactions); let publicReactions = $ref($i.publicReactions);
@ -86,6 +91,7 @@ function save() {
isLocked: !!isLocked, isLocked: !!isLocked,
autoAcceptFollowed: !!autoAcceptFollowed, autoAcceptFollowed: !!autoAcceptFollowed,
noCrawle: !!noCrawle, noCrawle: !!noCrawle,
preventAiLarning: !!preventAiLarning,
isExplorable: !!isExplorable, isExplorable: !!isExplorable,
hideOnlineStatus: !!hideOnlineStatus, hideOnlineStatus: !!hideOnlineStatus,
publicReactions: !!publicReactions, publicReactions: !!publicReactions,