Code Rebase - 1.0.0 by itzdrli
This commit is contained in:
parent
50cba9e6be
commit
db1a9e33e6
@ -1,6 +0,0 @@
|
|||||||
pull_request_title: 'i18n: update translations'
|
|
||||||
pull_request_labels:
|
|
||||||
- i18n
|
|
||||||
files:
|
|
||||||
- source: /src/locales/zh-CN.yml
|
|
||||||
translation: /src/locales/%locale%.yml
|
|
17
package.json
17
package.json
@ -1,25 +1,25 @@
|
|||||||
{
|
{
|
||||||
"name": "koishi-plugin-market-info",
|
"name": "koishi-plugin-market-info-plus",
|
||||||
"description": "Koishi plugin market information",
|
"description": "Koishi plugin market information",
|
||||||
"version": "2.1.0",
|
"version": "1.0.0",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"typings": "lib/index.d.ts",
|
"typings": "lib/index.d.ts",
|
||||||
"files": [
|
"files": [
|
||||||
"lib",
|
"lib",
|
||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
"author": "Shigma <shigma10826@gmail.com>",
|
"author": "itzdrli <itzdrli@proton.me>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/koishijs/koishi-plugin-market-info.git"
|
"url": "git+https://github.com/itzdrli/koishi-plugin-market-info-plus.git"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/koishijs/koishi-plugin-market-info/issues"
|
"url": "https://github.com/itzdrli/koishi-plugin-market-info-plus/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/koishijs/koishi-plugin-market-info#readme",
|
"homepage": "https://github.com/itzdrli/koishi-plugin-market-info-plus#readme",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "atsc -b"
|
"build": "yakumo build"
|
||||||
},
|
},
|
||||||
"koishi": {
|
"koishi": {
|
||||||
"description": {
|
"description": {
|
||||||
@ -39,13 +39,14 @@
|
|||||||
"manager"
|
"manager"
|
||||||
],
|
],
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"koishi": "^4.15.0"
|
"koishi": "^4.17.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@koishijs/registry": "^6.0.4",
|
"@koishijs/registry": "^6.0.4",
|
||||||
"@types/node": "^20.8.10",
|
"@types/node": "^20.8.10",
|
||||||
"atsc": "^1.2.2",
|
"atsc": "^1.2.2",
|
||||||
"koishi": "^4.15.0",
|
"koishi": "^4.15.0",
|
||||||
|
"koishi-plugin-puppeteer": "^3.9.0",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { Context, Dict, Schema, Time, deepEqual, pick, sleep } from 'koishi'
|
import { Context, Dict, Schema, Time, deepEqual, pick, sleep } from 'koishi'
|
||||||
import {} from '@koishijs/plugin-market'
|
import {} from '@koishijs/plugin-market'
|
||||||
import type { SearchObject, SearchResult } from '@koishijs/registry'
|
import type { SearchObject, SearchResult } from '@koishijs/registry'
|
||||||
|
import { } from 'koishi-plugin-puppeteer'
|
||||||
|
import { renderMarketUpdate } from './renderImage'
|
||||||
|
|
||||||
export const name = 'market-info'
|
export const name = 'market-info-plus'
|
||||||
|
|
||||||
interface Receiver {
|
interface Receiver {
|
||||||
platform: string
|
platform: string
|
||||||
@ -11,6 +13,8 @@ interface Receiver {
|
|||||||
guildId?: string
|
guildId?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const inject = ["puppeteer"]
|
||||||
|
|
||||||
const Receiver: Schema<Receiver> = Schema.object({
|
const Receiver: Schema<Receiver> = Schema.object({
|
||||||
platform: Schema.string().required().description('平台名称。'),
|
platform: Schema.string().required().description('平台名称。'),
|
||||||
selfId: Schema.string().required().description('机器人 ID。'),
|
selfId: Schema.string().required().description('机器人 ID。'),
|
||||||
@ -30,7 +34,7 @@ export interface Config {
|
|||||||
|
|
||||||
export const Config: Schema<Config> = Schema.object({
|
export const Config: Schema<Config> = Schema.object({
|
||||||
rules: Schema.array(Receiver).role('table').description('推送规则列表。'),
|
rules: Schema.array(Receiver).role('table').description('推送规则列表。'),
|
||||||
endpoint: Schema.string().default('https://registry.koishi.chat/index.json').description('插件市场地址。'),
|
endpoint: Schema.string().default('https://kp.itzdrli.cc').description('插件市场地址。'),
|
||||||
interval: Schema.number().default(Time.minute * 30).description('轮询间隔 (毫秒)。'),
|
interval: Schema.number().default(Time.minute * 30).description('轮询间隔 (毫秒)。'),
|
||||||
showHidden: Schema.boolean().default(false).description('是否显示隐藏的插件。'),
|
showHidden: Schema.boolean().default(false).description('是否显示隐藏的插件。'),
|
||||||
showDeletion: Schema.boolean().default(false).description('是否显示删除的插件。'),
|
showDeletion: Schema.boolean().default(false).description('是否显示删除的插件。'),
|
||||||
@ -39,9 +43,7 @@ export const Config: Schema<Config> = Schema.object({
|
|||||||
})
|
})
|
||||||
|
|
||||||
export function apply(ctx: Context, config: Config) {
|
export function apply(ctx: Context, config: Config) {
|
||||||
ctx.i18n.define('zh', require('./locales/zh-CN'))
|
const logger = ctx.logger('market-info-plus')
|
||||||
|
|
||||||
const logger = ctx.logger('market')
|
|
||||||
|
|
||||||
const makeDict = (result: SearchResult) => {
|
const makeDict = (result: SearchResult) => {
|
||||||
const dict: Dict<SearchObject> = {}
|
const dict: Dict<SearchObject> = {}
|
||||||
@ -72,24 +74,25 @@ export function apply(ctx: Context, config: Config) {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
if (options.receive) {
|
if (options.receive) {
|
||||||
if (index >= 0) return session.text('.not-modified')
|
if (index >= 0) return `未修改订阅信息。`
|
||||||
config.rules.push(pick(session, ['platform', 'selfId', 'channelId', 'guildId']))
|
config.rules.push(pick(session, ['platform', 'selfId', 'channelId', 'guildId']))
|
||||||
} else {
|
} else {
|
||||||
if (index < 0) return session.text('.not-modified')
|
if (index < 0) return `未修改订阅信息。`
|
||||||
config.rules.splice(index, 1)
|
config.rules.splice(index, 1)
|
||||||
}
|
}
|
||||||
ctx.scope.update(config, false)
|
ctx.scope.update(config, false)
|
||||||
return session.text('.updated')
|
return `已更新订阅信息。`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
const objects = Object.values(previous).filter(data => !data.manifest.hidden)
|
const objects = Object.values(previous).filter(data => !data.manifest.hidden)
|
||||||
return session.text('.overview', [objects.length])
|
return `当前共有 ${objects.length} 个插件`
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = previous[name]
|
const data = previous[name]
|
||||||
if (!data) return session.text('.not-found', [name])
|
if (!data) `未找到插件 ${name}。`
|
||||||
return session.text('.detail', data)
|
return `${data.shortname} (${data.package.version})\n\n` +
|
||||||
|
`发布者:@${data.package.publisher.username}`
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.setInterval(async () => {
|
ctx.setInterval(async () => {
|
||||||
@ -97,10 +100,12 @@ export function apply(ctx: Context, config: Config) {
|
|||||||
const diff = Object.keys({ ...previous, ...current }).map((name) => {
|
const diff = Object.keys({ ...previous, ...current }).map((name) => {
|
||||||
const version1 = previous[name]?.package.version
|
const version1 = previous[name]?.package.version
|
||||||
const version2 = current[name]?.package.version
|
const version2 = current[name]?.package.version
|
||||||
if (version1 === version2) return
|
if (version1 === version2) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!version1) {
|
if (!version1) {
|
||||||
let output = <p><i18n path="market-info.created"></i18n></p>
|
let output = `新增:${name} (${version2})`
|
||||||
if (config.showPublisher) output += ` (@${current[name].package.publisher.username})`
|
if (config.showPublisher) output += ` (@${current[name].package.publisher.username})`
|
||||||
if (config.showDescription) {
|
if (config.showDescription) {
|
||||||
const { description } = current[name].manifest
|
const { description } = current[name].manifest
|
||||||
@ -126,12 +131,18 @@ export function apply(ctx: Context, config: Config) {
|
|||||||
|
|
||||||
const content = ['[插件市场更新]', ...diff].join('\n')
|
const content = ['[插件市场更新]', ...diff].join('\n')
|
||||||
logger.info(content)
|
logger.info(content)
|
||||||
|
|
||||||
|
// Generate image
|
||||||
|
const image = await renderMarketUpdate(ctx, config, diff, previous)
|
||||||
|
|
||||||
const delay = ctx.root.config.delay.broadcast
|
const delay = ctx.root.config.delay.broadcast
|
||||||
for (let index = 0; index < config.rules.length; ++index) {
|
for (let index = 0; index < config.rules.length; ++index) {
|
||||||
if (index && delay) await sleep(delay)
|
if (index && delay) await sleep(delay)
|
||||||
const { platform, selfId, channelId, guildId } = config.rules[index]
|
const { platform, selfId, channelId, guildId } = config.rules[index]
|
||||||
const bot = ctx.bots.find(bot => bot.platform === platform && bot.selfId === selfId)
|
const bot = ctx.bots.find(bot => bot.platform === platform && bot.selfId === selfId)
|
||||||
bot.sendMessage(channelId, content, guildId)
|
// Send both text and image
|
||||||
|
await bot.sendMessage(channelId, content, guildId)
|
||||||
|
await bot.sendMessage(channelId, image, guildId)
|
||||||
}
|
}
|
||||||
}, config.interval)
|
}, config.interval)
|
||||||
})
|
})
|
@ -1,21 +0,0 @@
|
|||||||
commands:
|
|
||||||
market:
|
|
||||||
description: 插件市场信息
|
|
||||||
|
|
||||||
messages:
|
|
||||||
overview: 当前共有 {0} 个插件。
|
|
||||||
not-found: 未找到插件 {0}。
|
|
||||||
updated: 已更新订阅信息。
|
|
||||||
not-modified: 未修改订阅信息。
|
|
||||||
detail: |-
|
|
||||||
{name} ({version})
|
|
||||||
{manifest.description.zh || manifest.description.en}
|
|
||||||
options:
|
|
||||||
receive.true: 订阅到此频道
|
|
||||||
receive.false: 取消订阅到此频道
|
|
||||||
|
|
||||||
market-info:
|
|
||||||
header: '[插件市场更新]'
|
|
||||||
created: 新增:{0}
|
|
||||||
updated: 更新:{0} ({1} → {2})`
|
|
||||||
deleted: 移除:{0}
|
|
40
src/renderImage.ts
Normal file
40
src/renderImage.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { Context } from 'koishi'
|
||||||
|
import { Config } from './index'
|
||||||
|
|
||||||
|
// Dark theme colors
|
||||||
|
const dark = ['#2e3440', '#ffffff', '#434c5e']
|
||||||
|
|
||||||
|
export async function renderMarketUpdate(ctx: Context, config: Config, diff: string[], previous: any) {
|
||||||
|
const cardHtml = diff.map(item => {
|
||||||
|
return `
|
||||||
|
<div class="col-4 flex flex-col h-full w-full min-w-[250px] max-w-[350px]">
|
||||||
|
<div class="bg-[${dark[2]}] shadow-lg rounded-2xl p-4 flex flex-col justify-between h-full">
|
||||||
|
<h2 class="text-lg font-semibold mb-2 flex-grow break-words text-[${dark[1]}]">${item}</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}).join('')
|
||||||
|
|
||||||
|
const html = `
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>插件市场更新</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
</head>
|
||||||
|
<body class="bg-[${dark[0]}] text-[${dark[1]}]">
|
||||||
|
<div class="max-w-7xl mx-auto p-4">
|
||||||
|
<div class="text-center mb-5">
|
||||||
|
<div class="bg-[${dark[2]}] shadow-lg rounded-2xl py-4 px-6">
|
||||||
|
<p class="text-2xl font-bold text-[${dark[1]}]">[插件市场更新]</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-4 gap-3">
|
||||||
|
${cardHtml}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`
|
||||||
|
|
||||||
|
return await ctx.puppeteer.render(html)
|
||||||
|
}
|
@ -2,16 +2,22 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
"outDir": "lib",
|
"outDir": "lib",
|
||||||
"target": "es2020",
|
"target": "es2022",
|
||||||
"module": "commonjs",
|
"module": "esnext",
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"composite": true,
|
"composite": true,
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "bundler",
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
|
"resolveJsonModule": true,
|
||||||
"jsxImportSource": "@satorijs/element",
|
"jsxImportSource": "@satorijs/element",
|
||||||
|
"types": [
|
||||||
|
"node",
|
||||||
|
"yml-register/types"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src"
|
"src"
|
||||||
|
Loading…
Reference in New Issue
Block a user