Commit 99ae47b6 authored by nanahira's avatar nanahira

multi pic source

parent d21c4229
...@@ -57,7 +57,7 @@ export class PicSource { ...@@ -57,7 +57,7 @@ export class PicSource {
```ts ```ts
import { Context } from "koishi"; import { Context } from "koishi";
import { DefinePlugin, RegisterSchema, SchemaProperty, LifecycleEvents } from "koishi-thirdeye"; import { DefinePlugin, RegisterSchema, SchemaProperty, LifecycleEvents } from "koishi-thirdeye";
import { PicSource, PicsContainer, PicSourceConfig } from "koishi-plugin-pics"; import { PicSourcePlugin, PicsContainer, PicSourceConfig } from "koishi-plugin-pics";
@RegisterSchema() @RegisterSchema()
export class Config extends PicSourceConfig { export class Config extends PicSourceConfig {
...@@ -72,58 +72,59 @@ export default class MyPicSource extends PicSourcePlugin<Config> { ...@@ -72,58 +72,59 @@ export default class MyPicSource extends PicSourcePlugin<Config> {
return { url: `https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/${this.config.code}.jpg`, description: `${this.config.code}` }; return { url: `https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/${this.config.code}.jpg`, description: `${this.config.code}` };
} }
} }
// 加载图源插件
ctx.plugin(MyPicSource, {
code: 10000,
name: 'my-picsource',
description: 'my-picsource'
});
``` ```
#### 多图源 #### 多图源
使用 `DefineMultiSourcePlugin` 方法创建多图源插件。该插件的配置具有 `instances` 数组属性,每一项都是一个图源的配置。
```ts ```ts
import { Context } from "koishi"; import { Context } from "koishi";
import { DefinePlugin, RegisterSchema, SchemaProperty, LifecycleEvents } from "koishi-thirdeye"; import { DefinePlugin, RegisterSchema, SchemaProperty, LifecycleEvents } from "koishi-thirdeye";
import { PicSource, PicsContainer, PicSourceConfig } from "koishi-plugin-pics"; import { PicSourcePlugin, PicsContainer, PicSourceConfig } from "koishi-plugin-pics";
@RegisterSchema() @RegisterSchema()
export class InstanceConfig extends PicSourceConfig { export class Config extends PicSourceConfig {
@SchemaProperty({ default: 10000 }) @SchemaProperty({ default: 10000 })
code: number; code: number;
} }
@RegisterSchema() // 不 default
export class Config { @DefinePlugin({ name: 'my-picsource', schema: Config })
constructor(config: Partial<InstanceConfig>[]) {} export class MyPicSource extends PicSourcePlugin<Config> {
@SchemaProperty({ type: InstanceConfig })
instances: InstanceConfig[];
}
export class MyPicSourceInstance extends PicSource {
constructor(ctx: Context, config: Partial<Config>) {
super(ctx);
config.applyTo(this);
}
async randomPic(tags: string[]) { async randomPic(tags: string[]) {
return { url: `https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/${this.config.code}.jpg`, description: `${this.config.code}` }; return { url: `https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/${this.config.code}.jpg`, description: `${this.config.code}` };
} }
} }
// 在这里 default 加载插件
@DefinePlugin({ name: 'my-picsource', schema: Config }) export default class MyMultiPicSource extends DefineMultiSourcePlugin(
export default class MyPicSource extends BasePlugin<Config> implements LifecycleEvents { MyPicSource,
PicSourceConfig,
@InjectConfig() ) {}
private config: Config;
// 加载图源插件
@Inject(true) ctx.plugin(MyMultiPicSource, {
private pics: PicsContainer; instances: [
{
onApply() { code: 10000,
for (const instanceConfig of this.config.instances) { name: 'my-picsource1',
const instance = new MyPicSourceInstance(this.ctx, instanceConfig); description: 'my-picsource1',
this.pics.addSource(instance); },
} {
} code: 10001,
} name: 'my-picsource2',
description: 'my-picsource2',
},
].
});
``` ```
### 开箱即用的 Schema 定义 ### 开箱即用的 Schema 定义
......
import { Schema } from 'koishi';
import { Awaitable, Context } from 'koishi'; import { Awaitable, Context } from 'koishi';
import { DefinePlugin } from 'koishi-thirdeye'; import { DefinePlugin } from 'koishi-thirdeye';
import { PicResult, PicSourceConfig, PicSourcePlugin } from '../src'; import {
DefineMultiSourcePlugin,
PicResult,
PicSourceConfig,
PicSourcePlugin,
} from '../src';
@DefinePlugin({ schema: PicSourceConfig }) @DefinePlugin({ name: 'test-source', schema: PicSourceConfig })
class TestPicsource extends PicSourcePlugin { class TestPicSourcePlugin extends PicSourcePlugin {
randomPic(picTags: string[]): Awaitable<PicResult> { randomPic(picTags: string[]): Awaitable<PicResult> {
return { return {
url: `https://cdn02.moecube.com:444/images/ygopro-images-${this.name}/${ url: `https://cdn02.moecube.com:444/images/ygopro-images-${this.name}/${
...@@ -14,9 +20,18 @@ class TestPicsource extends PicSourcePlugin { ...@@ -14,9 +20,18 @@ class TestPicsource extends PicSourcePlugin {
} }
} }
export class TestMultiPicSourcePlugin extends DefineMultiSourcePlugin(
TestPicSourcePlugin,
PicSourceConfig,
) {}
console.log((TestMultiPicSourcePlugin['Config'] as Schema).dict.instances.type);
export default class ExtrasInDev { export default class ExtrasInDev {
constructor(ctx: Context) { constructor(ctx: Context) {
ctx.plugin(TestPicsource, { name: 'zh-CN', isDefault: true }); ctx.plugin(TestMultiPicSourcePlugin, {
instances: [{ name: 'zh-CN', isDefault: true }, { name: 'en-US' }],
});
} }
static using = ['pics'] as const; static using = ['pics'] as const;
......
import { Awaitable } from 'koishi'; import { Awaitable } from 'koishi';
import { ClassType, SchemaProperty } from 'koishi-thirdeye'; import { ClassType, SchemaClass, SchemaProperty } from 'koishi-thirdeye';
import { Context } from 'vm';
export interface PicSourceInfo { export interface PicSourceInfo {
tags?: string[]; tags?: string[];
...@@ -29,7 +30,6 @@ export interface Instances<T> { ...@@ -29,7 +30,6 @@ export interface Instances<T> {
instances: T[]; instances: T[];
} }
export function ToInstancesConfig<T>( export function ToInstancesConfig<T>(
instanceConfig: ClassType<T>, instanceConfig: ClassType<T>,
): new () => Instances<T> { ): new () => Instances<T> {
...@@ -37,9 +37,33 @@ export function ToInstancesConfig<T>( ...@@ -37,9 +37,33 @@ export function ToInstancesConfig<T>(
instances: T[]; instances: T[];
}; };
SchemaProperty({ type: instanceConfig, default: [] })( SchemaProperty({
instanceConfigClass.prototype, type: SchemaClass(instanceConfig),
'instances', default: [],
); array: true,
})(instanceConfigClass.prototype, 'instances');
return instanceConfigClass; return instanceConfigClass;
} }
export function ClonePlugin<P extends { new (...args: any[]): any }>(
target: P,
name: string,
): P {
const pluginName = target.name;
const clonedPlugin = class extends target {};
for (const property of ['Config', 'schema', 'using']) {
Object.defineProperty(clonedPlugin, property, {
enumerable: true,
configurable: true,
writable: true,
value: target[property],
});
}
Object.defineProperty(clonedPlugin, 'name', {
enumerable: true,
configurable: true,
writable: true,
value: pluginName,
});
return clonedPlugin;
}
import { Context, Awaitable, Logger } from 'koishi'; import { Context, Awaitable, Logger, Plugin } from 'koishi';
import { import {
PartialDeep, PartialDeep,
InjectConfig, InjectConfig,
Inject, Inject,
InjectLogger, InjectLogger,
BasePlugin, BasePlugin,
ClassType,
DefinePlugin,
LifecycleEvents,
} from 'koishi-thirdeye'; } from 'koishi-thirdeye';
import PicsContainer from '.'; import PicsContainer from '.';
import { PicSourceConfig } from './config'; import { PicSourceConfig } from './config';
import { PicSourceInfo, PicResult, Instances } from './def'; import {
PicSourceInfo,
PicResult,
Instances,
ToInstancesConfig,
ClonePlugin,
} from './def';
export class PicSource implements PicSourceInfo { export class PicSource implements PicSourceInfo {
constructor(protected ctx: Context) {} constructor(protected ctx: Context) {}
...@@ -62,16 +71,55 @@ export class PicSourcePlugin< ...@@ -62,16 +71,55 @@ export class PicSourcePlugin<
} }
} }
export class MultiPicSourcePlugin< export class MultiPicSourcePlugin<C extends PicSourceConfig>
C extends PicSourceConfig = PicSourceConfig, extends BasePlugin<Instances<C>>
> extends BasePlugin<Instances<C>> { implements LifecycleEvents
{
@Inject(true) @Inject(true)
protected pics: PicsContainer; protected pics: PicsContainer;
@InjectLogger() @InjectLogger()
protected logger: Logger; protected logger: Logger;
getSourcePlugin(): new (ctx: Context, config: any) => PicSourcePlugin<C> {
throw new Error(`Not implemented`);
}
registerSourceInstances() {
const sourcePlugin = this.getSourcePlugin();
for (const instanceConfig of this.config.instances) {
const clonedSourcePlugin = ClonePlugin(
sourcePlugin,
`${instanceConfig.name}-${instanceConfig.name}`,
);
this.ctx.plugin(clonedSourcePlugin, instanceConfig);
}
}
onApply() { onApply() {
const { instances } = this.config; this.registerSourceInstances();
} }
} }
export function DefineMultiSourcePlugin<
C extends PicSourceConfig,
P extends PicSourcePlugin<C>,
>(
SourcePlugin: new (ctx: Context, config: C) => P,
SourceConfig: ClassType<C>,
name = SourcePlugin.name,
): new (
context: Context,
config: Instances<PartialDeep<C>>,
) => MultiPicSourcePlugin<C> {
const pluginClass = class SpecificMultiPicSourcePlugin extends MultiPicSourcePlugin<C> {
getSourcePlugin() {
return SourcePlugin;
}
};
return DefinePlugin({
name,
schema: ToInstancesConfig(SourceConfig),
})(pluginClass);
}
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