Skip to content

Commit

Permalink
feat: add image size preference (#172)
Browse files Browse the repository at this point in the history
* feat: add image size preference

close #68

* fix: make url optional

* fix: allow to iterate different sizes

so that image source no need to apply all sizes in once

* fix: rename sample to thumbnail

* feat: add urls support for danbooru

* feat: add urls support for e621

* feat: add urls support for gelbooru

* feat: add urls support for konachan

* feat: add urls support for local

* feat: add urls support for lolibooru

* feat: add urls support for lolicon

* feat: add urls support for moehu

* feat: add urls support for safebooru

* feat: add urls support for sankaku

* feat: add urls support for yande.re

* feat: add urls support for pixiv
  • Loading branch information
MaikoTan authored Mar 21, 2024
1 parent 5266a54 commit 5d40eb9
Show file tree
Hide file tree
Showing 15 changed files with 103 additions and 21 deletions.
23 changes: 15 additions & 8 deletions packages/core/src/command.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Channel, Context, Random, Session, User } from 'koishi'
import { Config, OutputType, SpoilerType } from '.'
import { Config, OutputType, SpoilerType, preferSizes } from '.'

export const inject = {
required: ['booru'],
Expand Down Expand Up @@ -71,6 +71,14 @@ export function apply(ctx: Context, config: Config) {
const output: Element[] = []

for (const image of filtered) {
let url = ''
for (const size of preferSizes.slice(preferSizes.indexOf(config.preferSize))) {
url = image.urls?.[size]
if (url) {
break
}
}
url ||= image.url
if (config.showTips) {
const tips = getTips(session)
if (tips) {
Expand All @@ -85,15 +93,14 @@ export function apply(ctx: Context, config: Config) {
}

if (config.asset && ctx.assets) {
image.url = await ctx.booru.imgUrlToAssetUrl(image)
if (!image.url) {
url = await ctx.booru.imgUrlToAssetUrl(image)
if (!url) {
output.unshift(<i18n path='.no-image'></i18n>)
continue
}
}
if (config.base64) {
image.url = await ctx.booru.imgUrlToBase64(image)
if (!image.url) {
} else if (config.base64) {
url = await ctx.booru.imgUrlToBase64(image)
if (!url) {
output.unshift(<i18n path='.no-image'></i18n>)
continue
}
Expand Down Expand Up @@ -155,7 +162,7 @@ export function apply(ctx: Context, config: Config) {
return Boolean(image.nsfw)
}
})()}
src={image.url}
src={url}
></img>
</message>,
)
Expand Down
10 changes: 10 additions & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export interface Config {
confidence: number
maxCount: number
output: OutputType
preferSize: ImageSource.PreferSize
nsfw: boolean
asset: boolean
base64: boolean
Expand Down Expand Up @@ -172,6 +173,15 @@ export const Config = Schema.intersect([
])
.description('输出方式。')
.default(1),
preferSize: Schema.union([
Schema.const('original').description('原始尺寸'),
Schema.const('large').description('较大尺寸 (通常为约 1200px)'),
Schema.const('medium').description('中等尺寸 (通常为约 600px)'),
Schema.const('small').description('较小尺寸 (通常为约 300px)'),
Schema.const('thumbnail').description('缩略图'),
])
.description('优先使用图片的最大尺寸。')
.default('large'),
asset: Schema.boolean().default(false).description('优先使用 [assets服务](https://assets.koishi.chat/) 转存图片。'),
base64: Schema.boolean().default(false).description('使用 base64 发送图片。'),
spoiler: Schema.union([
Expand Down
14 changes: 13 additions & 1 deletion packages/core/src/source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,18 @@ export namespace ImageSource {

export type NsfwType = 'furry' | 'guro' | 'shota' | 'bl'

export enum PreferSize {
Original = 'original',
Large = 'large',
Medium = 'medium',
Small = 'small',
Thumbnail = 'thumbnail',
}

export interface Result {
url: string
/** @deprecated Use `.urls.*` instead */
url?: string
urls: Partial<Record<Exclude<PreferSize, 'origin'>, string>> & { original: string }
pageUrl?: string
author?: string
authorUrl?: string
Expand All @@ -79,3 +89,5 @@ export namespace ImageSource {
nsfw?: boolean | NsfwType
}
}

export const preferSizes = ['thumbnail', 'large', 'medium', 'small', 'original'] as const
7 changes: 6 additions & 1 deletion packages/danbooru/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ class DanbooruImageSource extends ImageSource<DanbooruImageSource.Config> {

return data.map((post) => {
return {
url: post.file_url,
// Size: file_url > large_file_url > preview_file_url
urls: {
original: post.file_url,
large: post.large_file_url,
thumbnail: post.preview_file_url,
},
pageUrl: post.source,
author: post.tag_string_artist.replace(/ /g, ', ').replace(/_/g, ' '),
tags: post.tag_string.split(' ').map((t) => t.replace(/_/g, ' ')),
Expand Down
7 changes: 6 additions & 1 deletion packages/e621/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ class e621ImageSource extends ImageSource<e621ImageSource.Config> {

return data.posts.map((post) => {
return {
url: post.file.url,
// Size: file > sample > preview
urls: {
original: post.file.url,
medium: post.sample.url,
thumbnail: post.preview.url,
},
pageUrl: trimSlash(this.config.endpoint) + `/post/${post.id}`,
author: post.tags.artist.join(', '),
tags: Object.values(post.tags).flat(),
Expand Down
7 changes: 6 additions & 1 deletion packages/gelbooru/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ class GelbooruImageSource extends ImageSource<GelbooruImageSource.Config> {

return data.post.map((post) => {
return {
url: post.file_url,
// Size: file_url > sample_url > preview_url
urls: {
original: post.file_url,
medium: post.sample_url,
thumbnail: post.preview_url,
},
pageUrl: post.source,
author: post.owner.replace(/ /g, ', ').replace(/_/g, ' '),
tags: post.tags.split(' ').map((t) => t.replace(/_/g, ' ')),
Expand Down
6 changes: 5 additions & 1 deletion packages/konachan/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ class KonachanImageSource extends ImageSource<KonachanImageSource.Config> {

return data.map((post) => {
return {
url: post.file_url,
urls: {
original: post.file_url,
medium: post.sample_url,
thumbnail: post.preview_url,
},
pageUrl: post.source,
author: post.author.replace(/ /g, ', ').replace(/_/g, ' '),
tags: post.tags.split(' ').map((t) => t.replace(/_/g, ' ')),
Expand Down
4 changes: 3 additions & 1 deletion packages/local/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ class LocalImageSource extends ImageSource<LocalImageSource.Config> {
const picker = Random.pick(pickPool, query.count)
return picker.map((img) => {
return {
url: pathToFileURL(img.path).href,
urls: {
original: pathToFileURL(img.path).href,
},
title: img.name,
// nsfw: img.nsfw,
tags: img.tags,
Expand Down
6 changes: 5 additions & 1 deletion packages/lolibooru/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ class LolibooruImageSource extends ImageSource<LolibooruImageSource.Config> {
// Since lolibooru returns URL that contains white spaces that are not transformed
// into `%20`, which breaks in go-cqhttp who cannot resolve to a valid URL.
// Fixes: https://github.com/koishijs/koishi-plugin-booru/issues/95
url: encodeURI(post.file_url),
urls: {
original: encodeURI(post.file_url),
medium: encodeURI(post.sample_url),
thumbnail: encodeURI(post.preview_url),
},
pageUrl: post.source,
author: post.author.replace(/ /g, ', ').replace(/_/g, ' '),
tags: post.tags.split(' ').map((t) => t.replace(/_/g, ' ')),
Expand Down
8 changes: 7 additions & 1 deletion packages/lolicon/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ class LoliconImageSource extends ImageSource<LoliconImageSource.Config> {
.filter((setu) => !!this.config.r18 || !!this.config.r18 === setu.r18)
.map((setu) => {
return {
url: setu.urls.original,
urls: {
original: setu.urls.original,
large: setu.urls.regular,
medium: setu.urls.small,
small: setu.urls.thumb,
thumbnail: setu.urls.mini,
},
title: setu.title,
author: setu.author,
nsfw: setu.r18,
Expand Down
4 changes: 3 additions & 1 deletion packages/moehu/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class MoehuImageSource extends ImageSource<MoehuImageSource.Config> {

return data.pic.map((img) => {
return {
url: img,
urls: {
original: img,
},
nsfw: false,
}
})
Expand Down
5 changes: 4 additions & 1 deletion packages/pixiv/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ class PixivImageSource extends ImageSource<PixivImageSource.Config> {
}

return {
url: await this._handleImage(url),
urls: {
// TODO: fill up other urls
original: await this._handleImage(url),
},
title: illust.title,
pageUrl: `https://pixiv.net/i/${illust.id}`,
author: illust.user.name,
Expand Down
11 changes: 10 additions & 1 deletion packages/safebooru/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,16 @@ class SafebooruImageSource extends ImageSource<SafebooruImageSource.Config> {

return data.map((post) => {
return {
url: `https://safebooru.org//${post.sample ? 'samples' : 'images'}/${post.directory}/${post.sample ? 'sample_' : ''}${post.image}?${post.id}`,
// Safebooru didn't straightly provide image urls, so we should construct them manually.
// `sample` url only exists when the image is too large, in that case, `post.sample`
// would be `true`, and then we could construct the sample url.
urls: {
original: `https://safebooru.org/images/${post.directory}/${post.image}?${post.id}`,
large: post.sample
? `https://safebooru.org/samples/${post.directory}/sample_${post.image}?${post.id}`
: undefined,
thumbnail: `https://safebooru.org/thumbnails/${post.directory}/thumbnail_${post.image}?${post.id}`,
},
// pageUrl: post.source,
author: post.owner.replace(/ /g, ', ').replace(/_/g, ' '),
tags: post.tags.split(' ').map((t) => t.replace(/_/g, ' ')),
Expand Down
6 changes: 5 additions & 1 deletion packages/sankaku/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ class SankakuComplexImageSource extends ImageSource<SankakuComplexImageSource.Co

return data.map((post) => {
return {
url: post.file_url,
urls: {
original: post.file_url,
medium: post.sample_url,
thumbnail: post.preview_url,
},
pageUrl: post.source,
author: post.author.name.replace(/ /g, ', ').replace(/_/g, ' '),
tags: post.tags.map((t) => t.name.replace(/_/g, ' ')),
Expand Down
6 changes: 5 additions & 1 deletion packages/yande/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ class YandeImageSource extends ImageSource<YandeImageSource.Config> {

return data.map((post) => {
return {
url: post.file_url,
urls: {
original: post.file_url,
medium: post.sample_url,
thumbnail: post.preview_url,
},
pageUrl: post.source,
author: post.author.replace(/ /g, ', ').replace(/_/g, ' '),
tags: post.tags.split(' ').map((t) => t.replace(/_/g, ' ')),
Expand Down

0 comments on commit 5d40eb9

Please sign in to comment.