Skip to content

Commit

Permalink
spec(frontend): Skeb Buttonの実装 (#573)
Browse files Browse the repository at this point in the history
  • Loading branch information
u1-liquid authored Mar 29, 2024
1 parent 197e397 commit efc5d97
Show file tree
Hide file tree
Showing 16 changed files with 483 additions and 4 deletions.
16 changes: 15 additions & 1 deletion locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2575,4 +2575,18 @@ _reversi:
_offlineScreen:
title: "Offline - cannot connect to the server"
header: "Unable to connect to the server"

_skebStatus:
_genres:
art: "Artwork"
comic: "Comic"
voice: "Voice"
novel: "Text"
video: "Movie"
music: "Music"
correction: "Advice"
seeking: "Seeking"
stopped: "Stopped"
client: "Client"
yenX: "JPY {x}"
nWorks: "Delivered {n} works"
nRequests: "Requested {n} times"
56 changes: 56 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10113,6 +10113,62 @@ export interface Locale extends ILocale {
*/
"summaryProxyDescription2": string;
};
"_skebStatus": {
"_genres": {
/**
* イラスト
*/
"art": string;
/**
* コミック
*/
"comic": string;
/**
* ボイス
*/
"voice": string;
/**
* テキスト
*/
"novel": string;
/**
* ムービー
*/
"video": string;
/**
* ミュージック
*/
"music": string;
/**
* アドバイス
*/
"correction": string;
};
/**
* 募集中
*/
"seeking": string;
/**
* 停止中
*/
"stopped": string;
/**
* クライアント
*/
"client": string;
/**
* {x}円
*/
"yenX": ParameterizedString<"x">;
/**
* 納品実績 {n}件
*/
"nWorks": ParameterizedString<"n">;
/**
* 取引実績 {n}件
*/
"nRequests": ParameterizedString<"n">;
};
}
declare const locales: {
[lang: string]: Locale;
Expand Down
16 changes: 16 additions & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2693,3 +2693,19 @@ _urlPreviewSetting:
summaryProxy: "プレビューを生成するプロキシのエンドポイント"
summaryProxyDescription: "Misskey本体ではなく、サマリープロキシを使用してプレビューを生成します。"
summaryProxyDescription2: "プロキシには下記パラメータがクエリ文字列として連携されます。プロキシ側がこれらをサポートしない場合、設定値は無視されます。"

_skebStatus:
_genres:
art: "イラスト"
comic: "コミック"
voice: "ボイス"
novel: "テキスト"
video: "ムービー"
music: "ミュージック"
correction: "アドバイス"
seeking: "募集中"
stopped: "停止中"
client: "クライアント"
yenX: "{x}円"
nWorks: "納品実績 {n}件"
nRequests: "取引実績 {n}件"
16 changes: 15 additions & 1 deletion locales/ko-KR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2549,4 +2549,18 @@ _reversi:
_offlineScreen:
title: "오프라인 - 서버에 접속할 수 없습니다"
header: "서버에 접속할 수 없습니다"

_skebStatus:
_genres:
art: "작품"
comic: "만화"
voice: "음성"
novel: "텍스트"
video: "동영상"
music: "음악"
correction: "조언"
seeking: "모집 중"
stopped: "정지 중"
client: "클라이언트"
yenX: "JPY {x}"
nWorks: "납품 실적 {n}건"
nRequests: "거래 실적 {n}건"
16 changes: 16 additions & 0 deletions packages/backend/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ type Source = {
scope?: 'local' | 'global' | string[];
};

skebStatus?: {
method: string;
endpoint: string;
headers: { [x: string]: string };
parameters: { [x: string]: string };
userIdParameterName: string;
}

proxy?: string;
proxySmtp?: string;
proxyBypassHosts?: string[];
Expand Down Expand Up @@ -140,6 +148,13 @@ export type Config = {
index: string;
scope?: 'local' | 'global' | string[];
} | undefined;
skebStatus: {
method: string;
endpoint: string;
headers: { [x: string]: string };
parameters: { [x: string]: string };
userIdParameterName: string;
} | undefined;
proxy: string | undefined;
proxySmtp: string | undefined;
proxyBypassHosts: string[] | undefined;
Expand Down Expand Up @@ -266,6 +281,7 @@ export function loadConfig(): Config {
redisForObjectStorageQueue: config.redisForObjectStorageQueue ? convertRedisOptions(config.redisForObjectStorageQueue, host) : redisForJobQueue,
redisForWebhookDeliverQueue: config.redisForWebhookDeliverQueue ? convertRedisOptions(config.redisForWebhookDeliverQueue, host) : redisForJobQueue,
redisForTimelines: config.redisForTimelines ? convertRedisOptions(config.redisForTimelines, host) : redis,
skebStatus: config.skebStatus,
id: config.id,
proxy: config.proxy,
proxySmtp: config.proxySmtp,
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/core/entities/MetaEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export class MetaEntityService {

mediaProxy: this.config.mediaProxy,
enableUrlPreview: instance.urlPreviewEnabled,
enableSkebStatus: !!this.config.skebStatus,
};
}

Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/models/json-schema/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ export const packedMetaLiteSchema = {
type: 'boolean',
optional: false, nullable: false,
},
enableSkebStatus: {
type: 'boolean',
optional: false, nullable: false,
},
backgroundImageUrl: {
type: 'string',
optional: false, nullable: true,
Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/server/api/EndpointsModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ import * as ep___users_following from './endpoints/users/following.js';
import * as ep___users_gallery_posts from './endpoints/users/gallery/posts.js';
import * as ep___users_getFollowingBirthdayUsers from './endpoints/users/get-following-birthday-users.js';
import * as ep___users_getFrequentlyRepliedUsers from './endpoints/users/get-frequently-replied-users.js';
import * as ep___users_getSkebStatus from './endpoints/users/get-skeb-status.js';
import * as ep___users_featuredNotes from './endpoints/users/featured-notes.js';
import * as ep___users_lists_create from './endpoints/users/lists/create.js';
import * as ep___users_lists_delete from './endpoints/users/lists/delete.js';
Expand Down Expand Up @@ -736,6 +737,7 @@ const $users_following: Provider = { provide: 'ep:users/following', useClass: ep
const $users_gallery_posts: Provider = { provide: 'ep:users/gallery/posts', useClass: ep___users_gallery_posts.default };
const $users_getFollowingBirthdayUsers: Provider = { provide: 'ep:users/get-following-birthday-users', useClass: ep___users_getFollowingBirthdayUsers.default };
const $users_getFrequentlyRepliedUsers: Provider = { provide: 'ep:users/get-frequently-replied-users', useClass: ep___users_getFrequentlyRepliedUsers.default };
const $users_getSkebStatus: Provider = { provide: 'ep:users/get-skeb-status', useClass: ep___users_getSkebStatus.default };
const $users_featuredNotes: Provider = { provide: 'ep:users/featured-notes', useClass: ep___users_featuredNotes.default };
const $users_lists_create: Provider = { provide: 'ep:users/lists/create', useClass: ep___users_lists_create.default };
const $users_lists_delete: Provider = { provide: 'ep:users/lists/delete', useClass: ep___users_lists_delete.default };
Expand Down Expand Up @@ -1126,6 +1128,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$users_gallery_posts,
$users_getFollowingBirthdayUsers,
$users_getFrequentlyRepliedUsers,
$users_getSkebStatus,
$users_featuredNotes,
$users_lists_create,
$users_lists_delete,
Expand Down Expand Up @@ -1508,6 +1511,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$users_gallery_posts,
$users_getFollowingBirthdayUsers,
$users_getFrequentlyRepliedUsers,
$users_getSkebStatus,
$users_featuredNotes,
$users_lists_create,
$users_lists_delete,
Expand Down
2 changes: 2 additions & 0 deletions packages/backend/src/server/api/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ import * as ep___users_following from './endpoints/users/following.js';
import * as ep___users_gallery_posts from './endpoints/users/gallery/posts.js';
import * as ep___users_getFollowingBirthdayUsers from './endpoints/users/get-following-birthday-users.js';
import * as ep___users_getFrequentlyRepliedUsers from './endpoints/users/get-frequently-replied-users.js';
import * as ep___users_getSkebStatus from './endpoints/users/get-skeb-status.js';
import * as ep___users_featuredNotes from './endpoints/users/featured-notes.js';
import * as ep___users_lists_create from './endpoints/users/lists/create.js';
import * as ep___users_lists_delete from './endpoints/users/lists/delete.js';
Expand Down Expand Up @@ -734,6 +735,7 @@ const eps = [
['users/gallery/posts', ep___users_gallery_posts],
['users/get-following-birthday-users', ep___users_getFollowingBirthdayUsers],
['users/get-frequently-replied-users', ep___users_getFrequentlyRepliedUsers],
['users/get-skeb-status', ep___users_getSkebStatus],
['users/featured-notes', ep___users_featuredNotes],
['users/lists/create', ep___users_lists_create],
['users/lists/delete', ep___users_lists_delete],
Expand Down
148 changes: 148 additions & 0 deletions packages/backend/src/server/api/endpoints/users/get-skeb-status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { LoggerService } from '@/core/LoggerService.js';
import { HttpRequestService } from '@/core/HttpRequestService.js';
import type { Config } from '@/config.js';
import { ApiError } from '../../error.js';

export const meta = {
tags: ['users'],

requireCredential: false,
allowGet: true,
cacheSec: 60 * 5,

res: {
type: 'object',
properties: {
screenName: {
type: 'string',
optional: false, nullable: false,
},
isCreator: {
type: 'boolean',
optional: false, nullable: false,
},
isAcceptable: {
type: 'boolean',
optional: false, nullable: false,
},
creatorRequestCount: {
type: 'integer',
optional: false, nullable: false,
},
clientRequestCount: {
type: 'integer',
optional: false, nullable: false,
},
skills: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
properties: {
amount: {
type: 'integer',
optional: false, nullable: false,
},
genre: {
type: 'string',
optional: false, nullable: false,
enum: ['art', 'comic', 'voice', 'novel', 'video', 'music', 'correction'],
},
},
},
},
},
},

errors: {
skebStatusNotAvailable: {
message: 'Skeb status is not available.',
code: 'SKEB_STATUS_NOT_AVAILABLE',
id: '1dd37c9c-7e97-4c24-be98-227a78b21d80',
httpStatusCode: 403,
},

noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '88d582ae-69d9-45e0-a8b3-13f9945e48bf',
httpStatusCode: 404,
},
},
} as const;

export const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
} as const;

@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
@Inject(DI.config)
private config: Config,

private loggerService: LoggerService,
private httpRequestService: HttpRequestService,
) {
super(meta, paramDef, async (ps) => {
if (!this.config.skebStatus) throw new ApiError(meta.errors.skebStatusNotAvailable);
const logger = this.loggerService.getLogger('api:users:get-skeb-status');

const url = new URL(this.config.skebStatus.endpoint);
for (const [key, value] of Object.entries(this.config.skebStatus.parameters)) {
url.searchParams.set(key, value);
}
url.searchParams.set(this.config.skebStatus.userIdParameterName, ps.userId);

logger.info('Requesting Skeb status', { url: url.href, userId: ps.userId });
const res = await this.httpRequestService.send(
url.href,
{
method: this.config.skebStatus.method,
headers: {
...this.config.skebStatus.headers,
Accept: 'application/json',
},
timeout: 5000,
},
{
throwErrorWhenResponseNotOk: false,
},
);

const json = (await res.json()) as {
screen_name: string,
is_creator: boolean,
is_acceptable: boolean,
creator_request_count: number,
client_request_count: number,
skills: { amount: number, genre: 'art' | 'comic' | 'voice' | 'novel' | 'video' | 'music' | 'correction' }[],
ban_reason?: string | null
error?: unknown,
};

if (res.status > 399 || (json.error ?? json.ban_reason)) {
logger.error('Skeb status response error', { url: url.href, userId: ps.userId, status: res.status, statusText: res.statusText, error: json.error ?? json.ban_reason });
throw new ApiError(meta.errors.noSuchUser);
}

logger.info('Skeb status response', { url: url.href, userId: ps.userId, status: res.status, statusText: res.statusText, skebStatus: json });

return {
screenName: json.screen_name,
isCreator: json.is_creator,
isAcceptable: json.is_acceptable,
creatorRequestCount: json.creator_request_count,
clientRequestCount: json.client_request_count,
skills: json.skills,
};
});
}
}
Loading

0 comments on commit efc5d97

Please sign in to comment.