Skip to content

Commit

Permalink
feat: proxy support for image sources (#145)
Browse files Browse the repository at this point in the history
* feat: proxy support for image sources

* feat: migrate `this.ctx.http` to `this.http`

* fix: danbooru get error

* fix: initialise new Quester instance only proxyAgent is set

* refactor: migrate legacy `.axios()` to `.get()`
  • Loading branch information
MaikoTan authored Mar 10, 2024
1 parent 23f8c07 commit bf97124
Show file tree
Hide file tree
Showing 13 changed files with 39 additions and 26 deletions.
2 changes: 1 addition & 1 deletion docs/zh-CN/develop/source.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class LoliconImageSource extends ImageSource<LoliconImageSource.Config> {
// 注:根据图源设计规范,当 `query.tags` 为空数组或空时,应当返回随机图片。
// 由于 Lolicon API 默认对空标签会返回随机图,因此不需要做特别处理,
// 但对于其他图源可能需要传入特别的参数才能使用随机图片功能。
const resp = await this.ctx.http.post('https://api.lolicon.app/setu/v2', param)
const resp = await this.http.post('https://api.lolicon.app/setu/v2', param)

if (!Array.isArray(resp.data)) {
return
Expand Down
2 changes: 2 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@
}
},
"peerDependencies": {
"@koishijs/plugin-proxy-agent": "^0.1.4",
"koishi": "^4.17.0"
},
"devDependencies": {
"@koishijs/assets": "^1.0.2",
"@koishijs/plugin-proxy-agent": "^0.1.4",
"koishi": "^4.17.0"
},
"dependencies": {
Expand Down
23 changes: 17 additions & 6 deletions packages/core/src/source.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Context, Schema } from 'koishi'
import { Context, Quester, Schema } from 'koishi'
import type {} from '@koishijs/plugin-proxy-agent'
import type { Inject } from 'cordis'

export abstract class ImageSource<Config extends ImageSource.Config = ImageSource.Config> {
Expand All @@ -7,13 +8,17 @@ export abstract class ImageSource<Config extends ImageSource.Config = ImageSourc
languages: string[] = []
source: string

http: Quester

constructor(public ctx: Context, public config: Config) {
this.ctx.booru.register(this)

this.http = config.proxyAgent ? ctx.http.extend({ proxyAgent: config.proxyAgent }) : ctx.http
}

/**
* split query into tags, default implementation is comma-separated.
*
*
* e.g. `tag1, wordy tag2, UPPER CASED tag3` => `['tag1', 'wordy_tag2', 'upper_cased_tag3']`
*/
tokenize(query: string): string[] {
Expand All @@ -27,13 +32,19 @@ export namespace ImageSource {
export interface Config {
label: string
weight: number
proxyAgent: string
}

export function createSchema(o: { label: string }) {
return Schema.object({
label: Schema.string().default(o.label).description('图源标签,可用于在指令中手动指定图源。'),
weight: Schema.number().min(1).default(1).description('图源权重。在多个符合标签的图源中,将按照各自的权重随机选择。'),
}).description('全局设置')
return Schema.intersect([
Schema.object({
label: Schema.string().default(o.label).description('图源标签,可用于在指令中手动指定图源。'),
weight: Schema.number().min(1).default(1).description('图源权重。在多个符合标签的图源中,将按照各自的权重随机选择。'),
}).description('全局设置'),
Schema.object({
proxyAgent: Schema.string().default(undefined).description('请求图片时使用代理服务器。'),
}).description('请求设置'),
])
}

export const Config: Schema<Config> = createSchema({ label: 'default' })
Expand Down
6 changes: 3 additions & 3 deletions packages/danbooru/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ class DanbooruImageSource extends ImageSource<DanbooruImageSource.Config> {
}

async get(query: ImageSource.Query): Promise<ImageSource.Result[]> {
const resp = await this.ctx.http.axios<Danbooru.Post[]>(trimSlash(this.config.endpoint) + '/posts.json', { params: {
const data = await this.http.get<Danbooru.Post[]>(trimSlash(this.config.endpoint) + '/posts.json', { params: {
tags: query.tags.join(' '),
random: true,
limit: query.count,
}})

if (!Array.isArray(resp.data)) {
if (!Array.isArray(data)) {
return
}

return resp.data.map((post) => {
return data.map((post) => {
return {
url: post.file_url,
pageUrl: post.source,
Expand Down
8 changes: 4 additions & 4 deletions packages/e621/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class e621ImageSource extends ImageSource<e621ImageSource.Config> {

constructor(ctx: Context, config: e621ImageSource.Config) {
super(ctx, config)
this.http = ctx.http.extend({
this.http = this.http.extend({
headers: {
'User-Agent': config.userAgent
}
Expand All @@ -18,18 +18,18 @@ class e621ImageSource extends ImageSource<e621ImageSource.Config> {

async get(query: ImageSource.Query): Promise<ImageSource.Result[]> {
if (!query.tags.find(t => t.startsWith('order:'))) query.tags.push('order:random')
const resp = await this.http.axios<{
const data = await this.http.get<{
posts: e621.Post[]
}>(trimSlash(this.config.endpoint) + '/posts.json', { params: {
tags: query.tags.join(' '),
limit: query.count,
}})

if (!Array.isArray(resp.data.posts)) {
if (!Array.isArray(data.posts)) {
return
}

return resp.data.posts.map((post) => {
return data.posts.map((post) => {
return {
url: post.file.url,
pageUrl: trimSlash(this.config.endpoint) + `/post/${post.id}`,
Expand Down
2 changes: 1 addition & 1 deletion packages/gelbooru/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class GelbooruImageSource extends ImageSource<GelbooruImageSource.Config> {
}
const url = trimSlash(this.config.endpoint) + '?' + Object.entries(params).map(([key, value]) => `${key}=${value}`).join('&')

const { data } = await this.ctx.http.axios<Gelbooru.Response>(url)
const data = await this.http.get<Gelbooru.Response>(url)

if (!Array.isArray(data.post)) {
return
Expand Down
2 changes: 1 addition & 1 deletion packages/konachan/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class KonachanImageSource extends ImageSource<KonachanImageSource.Config> {
limit: query.count
}
const url = trimSlash(this.config.endpoint) + '/post.json' + '?' + Object.entries(params).map(([key, value]) => `${key}=${value}`).join('&')
const { data } = await this.ctx.http.axios<Konachan.Response[]>(url)
const data = await this.http.get<Konachan.Response[]>(url)

if (!Array.isArray(data)) {
return
Expand Down
2 changes: 1 addition & 1 deletion packages/lolibooru/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class LolibooruImageSource extends ImageSource<LolibooruImageSource.Config> {

const url = trimSlash(this.config.endpoint) + '/post/index.json' + '?' + Object.entries(params).map(([key, value]) => `${key}=${value}`).join('&')

const { data } = await this.ctx.http.axios<Lolibooru.Response[]>(url)
const data = await this.http.get<Lolibooru.Response[]>(url)

if (!Array.isArray(data)) {
return
Expand Down
2 changes: 1 addition & 1 deletion packages/lolicon/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class LoliconImageSource extends ImageSource<LoliconImageSource.Config> {
excludeAI: this.config.excludeAI,
proxy,
}
const resp = await this.ctx.http.post<Lolicon.Response>(this.config.endpoint, param)
const resp = await this.http.post<Lolicon.Response>(this.config.endpoint, param)

if (!Array.isArray(resp.data)) {
return
Expand Down
6 changes: 3 additions & 3 deletions packages/pixiv/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class PixivImageSource extends ImageSource<PixivImageSource.Config> {
await this._login()
}

return await this.ctx.http.get<PixivAppApi.Result>(trimSlash(this.config.endpoint) + url, {
return await this.http.get<PixivAppApi.Result>(trimSlash(this.config.endpoint) + url, {
params,
headers: this._getHeaders(),
})
Expand All @@ -93,7 +93,7 @@ class PixivImageSource extends ImageSource<PixivImageSource.Config> {
await this._login()
}

return await this.ctx.http.get<PixivAppApi.Result>(trimSlash(this.config.endpoint) + url, {
return await this.http.get<PixivAppApi.Result>(trimSlash(this.config.endpoint) + url, {
params: {
content_type: 'illust',
include_ranking_label: true,
Expand All @@ -116,7 +116,7 @@ class PixivImageSource extends ImageSource<PixivImageSource.Config> {
})

try {
const resp = await this.ctx.http.post(url, data, {
const resp = await this.http.post(url, data, {
headers: {
...this._getHeaders(),
'Content-Type': 'application/x-www-form-urlencoded',
Expand Down
2 changes: 1 addition & 1 deletion packages/safebooru/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class SafebooruImageSource extends ImageSource<SafebooruImageSource.Config> {
}
const url = trimSlash(this.config.endpoint) + '?' + Object.entries(params).map(([key, value]) => `${key}=${value}`).join('&')

const { data } = await this.ctx.http.axios<Safebooru.Response[]>(url)
const data = await this.http.get<Safebooru.Response[]>(url)

if (!Array.isArray(data)) {
return
Expand Down
2 changes: 1 addition & 1 deletion packages/sankaku/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SankakuComplexImageSource extends ImageSource<SankakuComplexImageSource.Co
}
const url = trimSlash(this.config.endpoint) + 'posts?' + Object.entries(params).map(([key, value]) => `${key}=${value}`).join('&')

const { data } = await this.ctx.http.axios<SankakuComplex.Response[]>(url)
const data = await this.http.get<SankakuComplex.Response[]>(url)

if (!Array.isArray(data)) return

Expand Down
6 changes: 3 additions & 3 deletions packages/yande/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ class YandeImageSource extends ImageSource<YandeImageSource.Config> {
}
const url = trimSlash(this.config.endpoint) + '/post.json' + '?' + Object.entries(params).map(([key, value]) => `${key}=${value}`).join('&')

const resp = await this.ctx.http.axios<Yande.Response[]>(url)
const data = await this.http.get<Yande.Response[]>(url)

if (!Array.isArray(resp.data)) {
if (!Array.isArray(data)) {
return
}

return resp.data.map((post) => {
return data.map((post) => {
return {
url: post.file_url,
pageUrl: post.source,
Expand Down

0 comments on commit bf97124

Please sign in to comment.