Skip to content

Commit

Permalink
feat: うごイラのサポート
Browse files Browse the repository at this point in the history
  • Loading branch information
hker9527 committed Nov 11, 2023
1 parent a983551 commit cbaf169
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './types/endpoints/v2/novel/bookmark/add'
export * from './types/endpoints/v1/illust/detail'
export * from './types/endpoints/v1/illust/recommended'
export * from './types/endpoints/v1/illust/series'
export * from './types/endpoints/v1/illust/ugoira/metadata'
export * from './types/endpoints/v1/manga/recommended'
export * from './types/endpoints/v1/novel/recommended'
export * from './types/endpoints/v1/novel/text'
Expand All @@ -19,6 +20,7 @@ export * from './types/error-response'
export * from './types/pixiv-common'
export * from './types/pixiv-illust-series'
export * from './types/pixiv-illust'
export * from './types/pixiv-ugoira'
export * from './types/pixiv-novel-series'
export * from './types/pixiv-novel'
export * from './types/pixiv-user'
Expand Down
6 changes: 6 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { PostV2NovelBookmarkAddRequest } from './types/endpoints/v2/novel/bookma
import { PostV1NovelBookmarkDeleteRequest } from './types/endpoints/v1/novel/bookmark/delete'
import { GetV1UserBookmarksIllustRequest } from './types/endpoints/v1/user/bookmarks/illust'
import { GetV1UserBookmarksNovelRequest } from './types/endpoints/v1/user/bookmarks/novel'
import { GetV1IllustUgoiraMetadataRequest } from './types/endpoints/v1/illust/ugoira/metadata'

/**
* 検索対象
Expand Down Expand Up @@ -189,6 +190,11 @@ export type MangaRecommendedOptions = SnakeToCamel<
Partial<GetV1MangaRecommendedRequest>
>

/**
* うごイラ詳細取得オプション
*/
export type UgoiraDetailOptions = SnakeToCamel<GetV1IllustUgoiraMetadataRequest>;

/**
* 小説詳細取得オプション
*/
Expand Down
12 changes: 12 additions & 0 deletions src/pixiv.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,18 @@ describe('pixiv', () => {
).toMatchSnapshot()
})

it('ugoiraDetail:83638393[ugoira]', async () => {
const ugoiraDetail = await pixiv.ugoiraMetadata({
illustId: 83_638_393
})
expect(ugoiraDetail.status).toBe(200)
// "medium": "https://i.pximg.net/img-zip-ugoira/img/2014/06/28/12/42/39/44360221_ugoira600x600.zip".
expect(ugoiraDetail.data.ugoira_metadata.zip_urls.medium).toMatch(
/^https:\/\/i\.pximg\.net\/img-zip-ugoira\/img\/.+_ugoira600x600\.zip$/
)
expect(ugoiraDetail.data.ugoira_metadata.frames).toHaveLength(96)
})

it('searchIllust', async () => {
const searchIllust = await pixiv.searchIllust({
word: 'ホロライブ',
Expand Down
27 changes: 27 additions & 0 deletions src/pixiv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
NovelBookmarkDeleteOptions,
UserBookmarksIllustOptions,
UserBookmarksNovelOptions,
UgoiraDetailOptions,
} from './options'
import { PixivApiError } from './types/error-response'
import {
Expand Down Expand Up @@ -94,6 +95,10 @@ import {
GetV1UserBookmarksIllustRequest,
GetV1UserBookmarksIllustResponse,
} from './types/endpoints/v1/user/bookmarks/illust'
import {
GetV1IllustUgoiraMetadataRequest,
GetV1IllustUgoiraMetadataResponse,
} from './types/endpoints/v1/illust/ugoira/metadata'

interface GetRequestOptions<T> {
method: 'GET'
Expand Down Expand Up @@ -384,6 +389,28 @@ export default class Pixiv {
})
}

// ---------- うごイラ ---------- //

/**
* うごイラの詳細情報を取得する。
*
* @param options オプション
* @returns レスポンス
*/
public async ugoiraMetadata(options: UgoiraDetailOptions) {
type RequestType = GetV1IllustUgoiraMetadataRequest
const parameters: RequestType = {
...this.convertSnakeToCamel(options),
illust_id: options.illustId,
}

return this.request<RequestType, GetV1IllustUgoiraMetadataResponse>({
method: 'GET',
path: '/v1/ugoira/metadata',
params: parameters,
})
}

// ---------- 小説 ---------- //

/**
Expand Down
41 changes: 41 additions & 0 deletions src/types/endpoints/v1/illust/ugoira/metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { BaseMultipleCheck, CheckFunctions } from '../../../../../checks'
import { PixivUgoiraItem, PixivUgoiraItemCheck } from '../../../../pixiv-ugoira'

/**
* GET /v1/illust/ugoira/detail のリクエスト
*/
export interface GetV1IllustUgoiraMetadataRequest {
/**
* イラストID
*/
illust_id: number
}

/**
* GET /v1/illust/ugoira/detail のレスポンス
*/
export interface GetV1IllustUgoiraMetadataResponse {
/**
* うごイラの詳細情報
*/
ugoira_metadata: PixivUgoiraItem
}

export class GetV1IllustUgoiraMetadataCheck extends BaseMultipleCheck<
GetV1IllustUgoiraMetadataRequest,
GetV1IllustUgoiraMetadataResponse
> {
requestChecks(): CheckFunctions<GetV1IllustUgoiraMetadataRequest> {
return {
illust_id: (data) => typeof data.illust_id === 'number',
}
}

responseChecks(): CheckFunctions<GetV1IllustUgoiraMetadataResponse> {
return {
ugoira_metadata: (data) =>
typeof data.ugoira_metadata === 'object' &&
new PixivUgoiraItemCheck().throwIfFailed(data.ugoira_metadata),
}
}
}
74 changes: 74 additions & 0 deletions src/types/pixiv-ugoira.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { BaseSimpleCheck, CheckFunctions } from "src/checks"

/**
* 圧縮されたフレームのURL
*
* ここのURLも {@link ImageUrls} と同様に、適切なリファラを付与する必要がある
*/
export interface ZipUrls {
/**
* 長辺が最大 600px
*
* "600x600" を "1920x1080" に変換したらオリジナル画像が得られる?
*/
medium: string
}

/**
* フレーム情報
*/
export interface Frames {
/**
* フレームのファイル名
*/
file: string
/**
* フレームの表示時間(ms)
*/
delay: number
}

/**
* pixiv うごイラアイテム
*/
export interface PixivUgoiraItem {
/**
* 圧縮されたフレームのURL
*/
zip_urls: ZipUrls
/**
* フレーム情報
*/
frames: Frames[]
}

export class ZipUrlsCheck extends BaseSimpleCheck<ZipUrls> {
checks(): CheckFunctions<ZipUrls> {
return {
medium: (data) => typeof data.medium === 'string',
}
}
}

export class FramesCheck extends BaseSimpleCheck<Frames> {
checks(): CheckFunctions<Frames> {
return {
file: (data) => typeof data.file === 'string',
delay: (data) => typeof data.delay === 'number',
}
}
}

export class PixivUgoiraItemCheck extends BaseSimpleCheck<PixivUgoiraItem> {
checks(): CheckFunctions<PixivUgoiraItem> {
return {
zip_urls: (data) =>
typeof data.zip_urls === 'object' &&
new ZipUrlsCheck().throwIfFailed(data.zip_urls),
frames: (data) =>
typeof data.frames === 'object' &&
Array.isArray(data.frames) &&
data.frames.every((frame) => new FramesCheck().throwIfFailed(frame)),
}
}
}

0 comments on commit cbaf169

Please sign in to comment.