koishi-plugin-luogu-saver-bot 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +209 -42
- package/package.json +7 -4
package/lib/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
2
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
7
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
8
|
var __export = (target, all) => {
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -43,6 +53,9 @@ function statusToString(status) {
|
|
|
43
53
|
__name(statusToString, "statusToString");
|
|
44
54
|
|
|
45
55
|
// src/index.ts
|
|
56
|
+
var import_markdown_it = __toESM(require("markdown-it"));
|
|
57
|
+
var import_markdown_it_katex = __toESM(require("markdown-it-katex"));
|
|
58
|
+
var import_highlight = __toESM(require("highlight.js"));
|
|
46
59
|
var name = "luogu-saver-bot";
|
|
47
60
|
var inject = ["puppeteer"];
|
|
48
61
|
var Config = import_koishi.Schema.object({
|
|
@@ -62,7 +75,6 @@ var LuoguSaverClient = class {
|
|
|
62
75
|
buildUrl(path) {
|
|
63
76
|
const base = this.endpoint.replace(/\/$/, "");
|
|
64
77
|
if (!base) return path;
|
|
65
|
-
console.log(`${base}${path}`);
|
|
66
78
|
if (path.startsWith("/")) return `${base}${path}`;
|
|
67
79
|
return `${base}/${path}`;
|
|
68
80
|
}
|
|
@@ -119,6 +131,183 @@ var LuoguSaverClient = class {
|
|
|
119
131
|
return res.data;
|
|
120
132
|
}
|
|
121
133
|
};
|
|
134
|
+
var md = new import_markdown_it.default({
|
|
135
|
+
html: true,
|
|
136
|
+
// 允许 HTML 标签
|
|
137
|
+
breaks: true,
|
|
138
|
+
// 转换换行符为 <br>
|
|
139
|
+
linkify: true,
|
|
140
|
+
// 自动识别链接
|
|
141
|
+
highlight: /* @__PURE__ */ __name(function(str, lang) {
|
|
142
|
+
if (lang && import_highlight.default.getLanguage(lang)) {
|
|
143
|
+
try {
|
|
144
|
+
return '<pre class="hljs"><code>' + import_highlight.default.highlight(str, { language: lang, ignoreIllegals: true }).value + "</code></pre>";
|
|
145
|
+
} catch (__) {
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + "</code></pre>";
|
|
149
|
+
}, "highlight")
|
|
150
|
+
});
|
|
151
|
+
md.use(import_markdown_it_katex.default);
|
|
152
|
+
function generateHtml(title, authorInfo, markdownContent) {
|
|
153
|
+
const renderedBody = md.render(markdownContent);
|
|
154
|
+
return `<!doctype html>
|
|
155
|
+
<html>
|
|
156
|
+
<head>
|
|
157
|
+
<meta charset="utf-8">
|
|
158
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
159
|
+
|
|
160
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.7.0/styles/github.min.css">
|
|
161
|
+
|
|
162
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css">
|
|
163
|
+
|
|
164
|
+
<style>
|
|
165
|
+
/* 基础重置与变量 */
|
|
166
|
+
:root {
|
|
167
|
+
--bg-color: #f6f8fa;
|
|
168
|
+
--card-bg: #ffffff;
|
|
169
|
+
--text-primary: #24292f;
|
|
170
|
+
--text-secondary: #57606a;
|
|
171
|
+
--border-color: #d0d7de;
|
|
172
|
+
--accent-color: #0969da;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
body {
|
|
176
|
+
margin: 0;
|
|
177
|
+
padding: 40px;
|
|
178
|
+
background-color: var(--bg-color);
|
|
179
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
|
180
|
+
color: var(--text-primary);
|
|
181
|
+
line-height: 1.5;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.container {
|
|
185
|
+
max-width: 900px;
|
|
186
|
+
margin: 0 auto;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.card {
|
|
190
|
+
background: var(--card-bg);
|
|
191
|
+
border: 1px solid var(--border-color);
|
|
192
|
+
border-radius: 6px;
|
|
193
|
+
padding: 32px 40px;
|
|
194
|
+
box-shadow: 0 3px 6px rgba(140, 149, 159, 0.15);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/* 头部信息 */
|
|
198
|
+
header {
|
|
199
|
+
border-bottom: 1px solid var(--border-color);
|
|
200
|
+
padding-bottom: 20px;
|
|
201
|
+
margin-bottom: 24px;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
h1.title {
|
|
205
|
+
margin: 0 0 8px 0;
|
|
206
|
+
font-size: 28px;
|
|
207
|
+
font-weight: 600;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.meta {
|
|
211
|
+
font-size: 14px;
|
|
212
|
+
color: var(--text-secondary);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* Markdown 内容美化 (仿 GitHub 风格) */
|
|
216
|
+
.markdown-body {
|
|
217
|
+
font-size: 16px;
|
|
218
|
+
line-height: 1.6;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.markdown-body h1, .markdown-body h2, .markdown-body h3 {
|
|
222
|
+
margin-top: 24px;
|
|
223
|
+
margin-bottom: 16px;
|
|
224
|
+
font-weight: 600;
|
|
225
|
+
line-height: 1.25;
|
|
226
|
+
}
|
|
227
|
+
.markdown-body h1 { font-size: 2em; padding-bottom: .3em; border-bottom: 1px solid #d0d7de; }
|
|
228
|
+
.markdown-body h2 { font-size: 1.5em; padding-bottom: .3em; border-bottom: 1px solid #d0d7de; }
|
|
229
|
+
.markdown-body h3 { font-size: 1.25em; }
|
|
230
|
+
|
|
231
|
+
.markdown-body p { margin-bottom: 16px; }
|
|
232
|
+
|
|
233
|
+
.markdown-body a { color: var(--accent-color); text-decoration: none; }
|
|
234
|
+
.markdown-body a:hover { text-decoration: underline; }
|
|
235
|
+
|
|
236
|
+
.markdown-body blockquote {
|
|
237
|
+
margin: 0 0 16px;
|
|
238
|
+
padding: 0 1em;
|
|
239
|
+
color: var(--text-secondary);
|
|
240
|
+
border-left: 0.25em solid var(--border-color);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.markdown-body ul, .markdown-body ol { padding-left: 2em; margin-bottom: 16px; }
|
|
244
|
+
|
|
245
|
+
/* 表格样式 */
|
|
246
|
+
.markdown-body table {
|
|
247
|
+
border-spacing: 0;
|
|
248
|
+
border-collapse: collapse;
|
|
249
|
+
margin-bottom: 16px;
|
|
250
|
+
width: max-content;
|
|
251
|
+
max-width: 100%;
|
|
252
|
+
overflow: auto;
|
|
253
|
+
display: block;
|
|
254
|
+
}
|
|
255
|
+
.markdown-body table th, .markdown-body table td {
|
|
256
|
+
padding: 6px 13px;
|
|
257
|
+
border: 1px solid var(--border-color);
|
|
258
|
+
}
|
|
259
|
+
.markdown-body table tr { background-color: #fff; border-top: 1px solid #c6cbd1; }
|
|
260
|
+
.markdown-body table tr:nth-child(2n) { background-color: #f6f8fa; }
|
|
261
|
+
|
|
262
|
+
/* 代码块微调 */
|
|
263
|
+
.markdown-body pre {
|
|
264
|
+
padding: 16px;
|
|
265
|
+
overflow: auto;
|
|
266
|
+
font-size: 85%;
|
|
267
|
+
line-height: 1.45;
|
|
268
|
+
background-color: #f6f8fa;
|
|
269
|
+
border-radius: 6px;
|
|
270
|
+
}
|
|
271
|
+
.markdown-body code {
|
|
272
|
+
padding: 0.2em 0.4em;
|
|
273
|
+
margin: 0;
|
|
274
|
+
font-size: 85%;
|
|
275
|
+
background-color: rgba(175,184,193,0.2);
|
|
276
|
+
border-radius: 6px;
|
|
277
|
+
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
|
|
278
|
+
}
|
|
279
|
+
.markdown-body pre code {
|
|
280
|
+
padding: 0;
|
|
281
|
+
background-color: transparent;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/* 图片自适应 */
|
|
285
|
+
.markdown-body img {
|
|
286
|
+
max-width: 100%;
|
|
287
|
+
box-sizing: content-box;
|
|
288
|
+
background-color: #fff;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* KaTeX 字体修复 */
|
|
292
|
+
.katex { font-size: 1.1em; }
|
|
293
|
+
</style>
|
|
294
|
+
</head>
|
|
295
|
+
<body>
|
|
296
|
+
<div class="container">
|
|
297
|
+
<div class="card">
|
|
298
|
+
<header>
|
|
299
|
+
<h1 class="title">${md.utils.escapeHtml(title)}</h1>
|
|
300
|
+
<div class="meta">${md.utils.escapeHtml(authorInfo)}</div>
|
|
301
|
+
</header>
|
|
302
|
+
<article class="markdown-body">
|
|
303
|
+
${renderedBody}
|
|
304
|
+
</article>
|
|
305
|
+
</div>
|
|
306
|
+
</div>
|
|
307
|
+
</body>
|
|
308
|
+
</html>`;
|
|
309
|
+
}
|
|
310
|
+
__name(generateHtml, "generateHtml");
|
|
122
311
|
function apply(ctx, config = {}) {
|
|
123
312
|
const endpoint = config.endpoint || "";
|
|
124
313
|
const userAgent = config.userAgent || "Uptime-Kuma";
|
|
@@ -147,18 +336,15 @@ function apply(ctx, config = {}) {
|
|
|
147
336
|
if (!id) return "请提供文章 ID";
|
|
148
337
|
const art = await ctx.luogu_saver.getArticle(id);
|
|
149
338
|
if (!art) return "未找到文章";
|
|
150
|
-
const
|
|
339
|
+
const rawContent = art.content ?? art.renderedContent ?? "";
|
|
151
340
|
const title = art.title ?? "";
|
|
152
|
-
const
|
|
153
|
-
const html =
|
|
341
|
+
const authorInfo = `作者 UID: ${art.authorId}`;
|
|
342
|
+
const html = generateHtml(title, authorInfo, rawContent);
|
|
154
343
|
if (!ctx.puppeteer) return "当前没有可用的 puppeteer 服务。";
|
|
155
344
|
const page = await ctx.puppeteer.page();
|
|
156
345
|
try {
|
|
157
346
|
const width = Number(options.width) || 960;
|
|
158
347
|
await page.setViewport({ width, height: 800, deviceScaleFactor: 2 });
|
|
159
|
-
if (typeof page.emulateMediaFeatures === "function") {
|
|
160
|
-
await page.emulateMediaFeatures([{ name: "prefers-color-scheme", value: "light" }]);
|
|
161
|
-
}
|
|
162
348
|
await page.setContent(html, { waitUntil: "networkidle0" });
|
|
163
349
|
try {
|
|
164
350
|
await page.evaluate(() => new Promise((resolve) => {
|
|
@@ -170,27 +356,19 @@ function apply(ctx, config = {}) {
|
|
|
170
356
|
loaded++;
|
|
171
357
|
return;
|
|
172
358
|
}
|
|
173
|
-
|
|
359
|
+
const handler = /* @__PURE__ */ __name(() => {
|
|
174
360
|
loaded++;
|
|
175
361
|
if (loaded === imgs.length) resolve(null);
|
|
176
|
-
});
|
|
177
|
-
img.addEventListener("
|
|
178
|
-
|
|
179
|
-
if (loaded === imgs.length) resolve(null);
|
|
180
|
-
});
|
|
362
|
+
}, "handler");
|
|
363
|
+
img.addEventListener("load", handler);
|
|
364
|
+
img.addEventListener("error", handler);
|
|
181
365
|
});
|
|
182
366
|
if (loaded === imgs.length) resolve(null);
|
|
367
|
+
setTimeout(() => resolve(null), 5e3);
|
|
183
368
|
}));
|
|
184
369
|
} catch (e) {
|
|
185
370
|
}
|
|
186
|
-
|
|
187
|
-
await page.evaluate(() => {
|
|
188
|
-
document.documentElement.style.background = "#ffffff";
|
|
189
|
-
if (document.body) document.body.style.background = "#ffffff";
|
|
190
|
-
});
|
|
191
|
-
} catch (e) {
|
|
192
|
-
}
|
|
193
|
-
const buffer = await page.screenshot({ fullPage: true, type: "png", omitBackground: false });
|
|
371
|
+
const buffer = await page.screenshot({ fullPage: true, type: "png" });
|
|
194
372
|
return import_koishi.h.image(buffer, "image/png");
|
|
195
373
|
} catch (err) {
|
|
196
374
|
ctx.logger.error("截图文章失败", err);
|
|
@@ -203,18 +381,15 @@ function apply(ctx, config = {}) {
|
|
|
203
381
|
if (!id) return "请提供剪贴板 ID";
|
|
204
382
|
const paste = await ctx.luogu_saver.getPaste(id);
|
|
205
383
|
if (!paste) return "未找到剪贴板内容";
|
|
206
|
-
const
|
|
207
|
-
const title = paste.id
|
|
208
|
-
const
|
|
209
|
-
const html =
|
|
384
|
+
const rawContent = paste.content ?? paste.renderedContent ?? "";
|
|
385
|
+
const title = `剪贴板: ${paste.id}`;
|
|
386
|
+
const authorInfo = paste.author ? `创建者: ${paste.author.name} (UID: ${paste.author.id})` : `创建者 UID: ${paste.authorId}`;
|
|
387
|
+
const html = generateHtml(title, authorInfo, rawContent);
|
|
210
388
|
if (!ctx.puppeteer) return "当前没有可用的 puppeteer 服务。";
|
|
211
389
|
const page = await ctx.puppeteer.page();
|
|
212
390
|
try {
|
|
213
391
|
const width = Number(options.width) || 960;
|
|
214
392
|
await page.setViewport({ width, height: 800, deviceScaleFactor: 2 });
|
|
215
|
-
if (typeof page.emulateMediaFeatures === "function") {
|
|
216
|
-
await page.emulateMediaFeatures([{ name: "prefers-color-scheme", value: "light" }]);
|
|
217
|
-
}
|
|
218
393
|
await page.setContent(html, { waitUntil: "networkidle0" });
|
|
219
394
|
try {
|
|
220
395
|
await page.evaluate(() => new Promise((resolve) => {
|
|
@@ -226,27 +401,19 @@ function apply(ctx, config = {}) {
|
|
|
226
401
|
loaded++;
|
|
227
402
|
return;
|
|
228
403
|
}
|
|
229
|
-
|
|
404
|
+
const handler = /* @__PURE__ */ __name(() => {
|
|
230
405
|
loaded++;
|
|
231
406
|
if (loaded === imgs.length) resolve(null);
|
|
232
|
-
});
|
|
233
|
-
img.addEventListener("
|
|
234
|
-
|
|
235
|
-
if (loaded === imgs.length) resolve(null);
|
|
236
|
-
});
|
|
407
|
+
}, "handler");
|
|
408
|
+
img.addEventListener("load", handler);
|
|
409
|
+
img.addEventListener("error", handler);
|
|
237
410
|
});
|
|
238
411
|
if (loaded === imgs.length) resolve(null);
|
|
412
|
+
setTimeout(() => resolve(null), 5e3);
|
|
239
413
|
}));
|
|
240
414
|
} catch (e) {
|
|
241
415
|
}
|
|
242
|
-
|
|
243
|
-
await page.evaluate(() => {
|
|
244
|
-
document.documentElement.style.background = "#ffffff";
|
|
245
|
-
if (document.body) document.body.style.background = "#ffffff";
|
|
246
|
-
});
|
|
247
|
-
} catch (e) {
|
|
248
|
-
}
|
|
249
|
-
const buffer = await page.screenshot({ fullPage: true, type: "png", omitBackground: false });
|
|
416
|
+
const buffer = await page.screenshot({ fullPage: true, type: "png" });
|
|
250
417
|
return import_koishi.h.image(buffer, "image/png");
|
|
251
418
|
} catch (err) {
|
|
252
419
|
ctx.logger.error("截图剪贴板失败", err);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-luogu-saver-bot",
|
|
3
3
|
"description": "洛谷保存站机器人",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.5",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -15,9 +15,12 @@
|
|
|
15
15
|
"koishi",
|
|
16
16
|
"plugin"
|
|
17
17
|
],
|
|
18
|
-
"devDependencies": {},
|
|
19
18
|
"peerDependencies": {
|
|
20
|
-
"koishi": "^4.18.7"
|
|
21
|
-
|
|
19
|
+
"koishi": "^4.18.7"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"highlight.js": "^11.11.1",
|
|
23
|
+
"markdown-it": "^14.1.0",
|
|
24
|
+
"markdown-it-katex": "^2.0.3"
|
|
22
25
|
}
|
|
23
26
|
}
|