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