Skip to content

Commit

Permalink
fix(core): transform command into sub-plugin and inject service (#130)
Browse files Browse the repository at this point in the history
* fix(core): transform command into sub-plugin and inject service

* bump version

* chore(core): fix end-line

* Revert "bump version"

This reverts commit 4dbdda6.
  • Loading branch information
Lipraty authored Dec 5, 2023
1 parent 56168e9 commit 42668a1
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 98 deletions.
104 changes: 104 additions & 0 deletions packages/core/src/command.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { Context, Session } from "koishi"
import { Config, OutputType, SpoilerType } from "."

export const inject = {
required: ['booru'],
optional: ['assets'],
}

export function apply(ctx: Context, config: Config) {

const count = (value: string, session: Session) => {
const count = parseInt(value)
if (count < 1 || count > config.maxCount) {
session.send('booru.count-invalid')
return 1
}
return count
}

ctx
.command('booru <query:text>')
.option('count', '-c <count:number>', { type: count, fallback: 1 })
.option('label', '-l <label:string>')
.action(async ({ session, options }, query) => {
if (!ctx.booru.hasSource(options.label)) return session.text('.no-source')

query = query?.trim() ?? ''

const images = await ctx.booru.get({
query,
count: options.count,
labels: options.label?.split(',')?.map((x) => x.trim())?.filter(Boolean) ?? [],
})
const source = images?.source

const filtered = images?.filter((image) => config.nsfw || !image.nsfw)

if (!filtered?.length) return session?.text('.no-result')

const output: Element[] = []

for (const image of filtered) {
if (config.asset && ctx.assets) {
image.url = await ctx.booru.imgUrlToAssetUrl(image)
if (!image.url) {
output.unshift(<i18n path=".no-image"></i18n>)
continue
}
}
if (config.base64) {
image.url = await ctx.booru.imgUrlToBase64(image)
if (!image.url) {
output.unshift(<i18n path=".no-image"></i18n>)
continue
}
}
switch (config.output) {
case OutputType.All:
if (image.tags)
output.unshift(<message>
<p><i18n path='.output.source'>{[source]}</i18n></p>
<p><i18n path='.output.tags'>{[image.tags.join(', ')]}</i18n></p>
</message>)
case OutputType.ImageAndLink:
if (image.pageUrl || image.authorUrl)
output.unshift(<message>
<p><i18n path='.output.link'>{[image.pageUrl]}</i18n></p>
<p><i18n path='.output.homepage'>{[image.authorUrl]}</i18n></p>
</message>)
case OutputType.ImageAndInfo:
if (image.title && image.author && image.desc)
output.unshift(<message>
<p>{image.title}</p>
<p><i18n path='.output.author'>{[image.author]}</i18n></p>
<p><i18n path='.output.desc'>{[image.desc]}</i18n></p>
</message>)
case OutputType.ImageOnly:
output.unshift(
/**
* @TODO waiting for upstream to support spoiler tag
* but is only is attribute, so it's can work now.
*/
<message>
<image spoiler={(() => {
switch (config.spoiler) {
case SpoilerType.Disabled:
return false
case SpoilerType.All:
return true
case SpoilerType.OnlyNSFW:
return Boolean(image.nsfw)
}
})()} url={image.url}></image></message>
)
}
}
// the qq platform will can merge the all forward message with one element(forward message block).
// so can treat it as a spoiler message.
if (['qq', 'red', 'onebot'].includes(session.platform) && config.spoiler !== SpoilerType.Disabled)
return <message forward>{output}</message>
else
return output.length === 1 ? output[0] : <message forward>{output}</message>
})
}
100 changes: 2 additions & 98 deletions packages/core/src/index.tsx → packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Context, Element, Logger, Quester, Schema, Service, Session } from 'koishi'
import LanguageDetect from 'languagedetect'
import { ImageSource } from './source'
import * as Command from './command'
import { } from '@koishijs/assets'

export * from './source'
Expand Down Expand Up @@ -169,107 +170,10 @@ export const Config = Schema.intersect([
}).description('输出设置'),
])

export const inject = {
required: [],
optional: ['assets'],
}

export function apply(ctx: Context, config: Config) {
ctx.plugin(ImageService, config)
ctx.plugin(Command, config)

ctx.i18n.define('zh', require('./locales/zh-CN'))

const count = (value: string, session: Session) => {
const count = parseInt(value)
if (count < 1 || count > config.maxCount) {
session.send('booru.count-invalid')
return 1
}
return count
}

ctx
.command('booru <query:text>')
.option('count', '-c <count:number>', { type: count, fallback: 1 })
.option('label', '-l <label:string>')
.action(async ({ session, options }, query) => {
if (!ctx.booru.hasSource(options.label)) return session.text('.no-source')

query = query?.trim() ?? ''

const images = await ctx.booru.get({
query,
count: options.count,
labels: options.label?.split(',')?.map((x) => x.trim())?.filter(Boolean) ?? [],
})
const source = images?.source

const filtered = images?.filter((image) => config.nsfw || !image.nsfw)

if (!filtered?.length) return session?.text('.no-result')

const output: Element[] = []

for (const image of filtered) {
if (config.asset && ctx.assets) {
image.url = await ctx.booru.imgUrlToAssetUrl(image)
if (!image.url) {
output.unshift(<i18n path=".no-image"></i18n>)
continue
}
}
if (config.base64) {
image.url = await ctx.booru.imgUrlToBase64(image)
if (!image.url) {
output.unshift(<i18n path=".no-image"></i18n>)
continue
}
}
switch (config.output) {
case OutputType.All:
if (image.tags)
output.unshift(<message>
<p><i18n path='.output.source'>{[source]}</i18n></p>
<p><i18n path='.output.tags'>{[image.tags.join(', ')]}</i18n></p>
</message>)
case OutputType.ImageAndLink:
if (image.pageUrl || image.authorUrl)
output.unshift(<message>
<p><i18n path='.output.link'>{[image.pageUrl]}</i18n></p>
<p><i18n path='.output.homepage'>{[image.authorUrl]}</i18n></p>
</message>)
case OutputType.ImageAndInfo:
if (image.title && image.author && image.desc)
output.unshift(<message>
<p>{image.title}</p>
<p><i18n path='.output.author'>{[image.author]}</i18n></p>
<p><i18n path='.output.desc'>{[image.desc]}</i18n></p>
</message>)
case OutputType.ImageOnly:
output.unshift(
/**
* @TODO waiting for upstream to support spoiler tag
* but is only is attribute, so it's can work now.
*/
<message>
<image spoiler={(() => {
switch (config.spoiler) {
case SpoilerType.Disabled:
return false
case SpoilerType.All:
return true
case SpoilerType.OnlyNSFW:
return Boolean(image.nsfw)
}
})()} url={image.url}></image></message>
)
}
}
// the qq platform will can merge the all forward message with one element(forward message block).
// so can treat it as a spoiler message.
if (['qq', 'red', 'onebot'].includes(session.platform) && config.spoiler !== SpoilerType.Disabled)
return <message forward>{output}</message>
else
return output.length === 1 ? output[0] : <message forward>{output}</message>
})
}

0 comments on commit 42668a1

Please sign in to comment.