Commit b63104f4 authored by nanahira's avatar nanahira

add getSegment

parent 547632df
...@@ -27,6 +27,6 @@ app.plugin(DatabasePlugin); ...@@ -27,6 +27,6 @@ app.plugin(DatabasePlugin);
app.plugin(ExtrasInDev); app.plugin(ExtrasInDev);
// Target plugin // Target plugin
app.plugin(TargetPlugin, {} as any); app.plugin(TargetPlugin, { useBase64: true });
app.start(); app.start();
// import 'source-map-support/register'; // import 'source-map-support/register';
import { DefineSchema, RegisterSchema, SchemaClass } from 'koishi-thirdeye'; import { DefineSchema, RegisterSchema, SchemaClass } from 'koishi-thirdeye';
import { Quester } from 'koishi';
@RegisterSchema() @RegisterSchema()
export class PicsPluginConfig { export class PicsPluginConfig {
...@@ -7,8 +8,17 @@ export class PicsPluginConfig { ...@@ -7,8 +8,17 @@ export class PicsPluginConfig {
@DefineSchema({ description: '指令名', default: 'pic', hidden: true }) @DefineSchema({ description: '指令名', default: 'pic', hidden: true })
commandName: string; commandName: string;
@DefineSchema({ description: '保留 URL 中的文件名。', default: false }) @DefineSchema({
preseveFilename: boolean; description: 'Assets 服务可用时,使用 Assets 缓存图片。',
default: true,
})
useAssets: boolean;
@DefineSchema({ description: '使用 Base64 发送图片结果。', default: false })
useBase64: boolean;
@DefineSchema({ type: Quester.createSchema(), default: {} })
httpConfig: Quester.Config;
} }
export type PicsPluginConfigLike = Partial<PicsPluginConfig>; export type PicsPluginConfigLike = Partial<PicsPluginConfig>;
......
// import 'source-map-support/register'; // import 'source-map-support/register';
import { Context, Assets, Awaitable, Random, Logger } from 'koishi'; import { Context, Assets, Awaitable, Random, Logger, Bot } from 'koishi';
import { PicSourceInfo, PicsPluginConfig } from './config'; import { PicSourceInfo, PicsPluginConfig } from './config';
import _ from 'lodash'; import _ from 'lodash';
import { segment } from 'koishi'; import { segment, Quester } from 'koishi';
import { import {
BasePlugin, BasePlugin,
Caller, Caller,
...@@ -75,6 +75,11 @@ export default class PicsContainer ...@@ -75,6 +75,11 @@ export default class PicsContainer
@Inject() @Inject()
private assets: Assets; private assets: Assets;
@Inject(true)
private http: Quester;
private _http: Quester;
addSource(source: PicSource, targetCtx?: Context) { addSource(source: PicSource, targetCtx?: Context) {
const processingCtx: Context = targetCtx || this.caller; const processingCtx: Context = targetCtx || this.caller;
const dispose = processingCtx.on('dispose', () => const dispose = processingCtx.on('dispose', () =>
...@@ -175,13 +180,41 @@ export default class PicsContainer ...@@ -175,13 +180,41 @@ export default class PicsContainer
return this.fetchPicsWithSources(sources, picTags); return this.fetchPicsWithSources(sources, picTags);
} }
async getSegment(url: string, bot?: Bot) {
try {
if (this.config.useAssets && this.assets) {
const uploadedUrl = await this.assets.upload(url, url.split('/').pop());
url = uploadedUrl;
} else if (this.config.useBase64) {
const buf = await this._http.get(url, {
responseType: 'arraybuffer',
});
url = `base64://${buf.toString('base64')}`;
}
} catch (e) {
this.logger.warn(`Download image ${url} failed: ${e.toString()}`);
}
const isOnebot =
bot &&
(bot.platform === 'onebot' ||
(bot.platform === 'qqguild' &&
bot['parentBot']?.platform === 'onebot'));
const picData: segment.Data = {
[isOnebot ? 'file' : 'url']: url,
cache: true,
};
return segment('image', picData);
}
async onApply() { async onApply() {
this._http = this.http.extend(this.config.httpConfig);
const ctx = this.ctx; const ctx = this.ctx;
ctx.i18n.define('zh', `commands.${this.config.commandName}`, { ctx.i18n.define('zh', `commands.${this.config.commandName}`, {
description: '获取随机图片', description: '获取随机图片',
options: { options: {
source: `指定图源,逗号分隔。图源可以用 ${this.config.commandName}.sources 查询。`, source: `指定图源,逗号分隔。图源可以用 ${this.config.commandName}.sources 查询。`,
}, },
usage: `从各个图源中随机获取一张随机图片。图源可以用 ${this.config.commandName}.sources 查询。参数均为可选。`,
messages: { messages: {
'not-found': '未找到任何图片。', 'not-found': '未找到任何图片。',
}, },
...@@ -189,6 +222,7 @@ export default class PicsContainer ...@@ -189,6 +222,7 @@ export default class PicsContainer
ctx.i18n.define('en', `commands.${this.config.commandName}`, { ctx.i18n.define('en', `commands.${this.config.commandName}`, {
description: 'Get random picture', description: 'Get random picture',
options: {}, options: {},
usage: `Get a random picture from a random sourse. Sources can be queried with command ${this.config.commandName}.sources`,
messages: { messages: {
'not-found': 'No pictures found.', 'not-found': 'No pictures found.',
}, },
...@@ -196,6 +230,7 @@ export default class PicsContainer ...@@ -196,6 +230,7 @@ export default class PicsContainer
ctx.i18n.define('zh', `commands.${this.config.commandName}.sources`, { ctx.i18n.define('zh', `commands.${this.config.commandName}.sources`, {
description: '查询图源列表', description: '查询图源列表',
options: {}, options: {},
usage: '图源标签可用于图片获取的图源筛选。',
messages: { messages: {
list: '图源的列表如下:', list: '图源的列表如下:',
}, },
...@@ -203,27 +238,18 @@ export default class PicsContainer ...@@ -203,27 +238,18 @@ export default class PicsContainer
ctx.i18n.define('en', `commands.${this.config.commandName}.sources`, { ctx.i18n.define('en', `commands.${this.config.commandName}.sources`, {
description: 'Query picture sources', description: 'Query picture sources',
options: {}, options: {},
usage: 'Source tags can be used to filter picture sources.',
messages: { messages: {
list: 'List of sources:', list: 'List of sources:',
}, },
}); });
ctx ctx
.command(`${this.config.commandName} [...tags:string]`, '获取随机图片') .command(`${this.config.commandName} [...tags:string]`)
.usage( .option('source', `-s <source:string>`)
`从各个图源中随机获取一张随机图片。图源可以用 ${this.config.commandName}.sources 查询。参数均为可选。`, .example(`${this.config.commandName}`)
) .example(`${this.config.commandName} yuyuko`)
.option( .example(`${this.config.commandName} -s yande`)
'source', .example(`${this.config.commandName} -s yande yuyuko saigyouji`)
`-s <source:string> 指定图源,逗号分隔。图源可以用 ${this.config.commandName}.sources 查询。`,
)
.example(`${this.config.commandName} 获取一张随机图片。`)
.example(`${this.config.commandName} yuyuko 获取一张 yuyuko 标签的图片。`)
.example(
`${this.config.commandName} -s yande 获取一张 yande 图源的图片。`,
)
.example(
`${this.config.commandName} -s yande yuyuko saigyouji 从 yande 图源中获取一张具有 yuyuko 以及 saigyouji 标签的图。`,
)
.action(async (argv, ...picTags) => { .action(async (argv, ...picTags) => {
const sourceTags = argv.options.source const sourceTags = argv.options.source
? argv.options.source.split(/[ ,+\uFF0C\uFF0B\u3001]/) ? argv.options.source.split(/[ ,+\uFF0C\uFF0B\u3001]/)
...@@ -233,27 +259,16 @@ export default class PicsContainer ...@@ -233,27 +259,16 @@ export default class PicsContainer
if (!result) { if (!result) {
return argv.session.text('.not-found'); return argv.session.text('.not-found');
} }
const picData: segment.Data = {
url: result.url, let msg = await this.getSegment(result.url, argv.session.bot);
cache: true,
};
if (this.config.preseveFilename) {
picData.file = result.url.split('/').pop();
}
let msg = segment('image', picData);
if (result.description) { if (result.description) {
msg += `\n${result.description}`; msg += `\n${result.description}`;
} }
if (this.assets) {
msg = await this.assets.transform(msg);
}
return msg; return msg;
}) })
.subcommand('.sources [...tags:string]', '查询图源列表') .subcommand('.sources [...tags:string]')
// .option('source', '-s <source:string> 要查询的图源标签,逗号分隔。') .example(`${this.config.commandName}.sources`)
.usage('图源标签可用于图片获取的图源筛选。') .example(`${this.config.commandName}.sources pixiv`)
.example(`${this.config.commandName}.sources 查询全部的图源。`)
.example(`${this.config.commandName} pixiv 查询含有 pixiv 标签的图源。`)
.action(async (argv, ...sourceTags) => { .action(async (argv, ...sourceTags) => {
sourceTags ||= []; sourceTags ||= [];
const sources = this.pickAvailableSources(sourceTags, true); const sources = this.pickAvailableSources(sourceTags, true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment