karin-plugin-kkk 1.3.0 → 1.4.0
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/CHANGELOG.md +16 -0
- package/config/default_config/bilibili.yaml +16 -0
- package/lib/Version.js +16 -0
- package/lib/apps/admin.js +190 -31
- package/lib/apps/help.js +31 -30
- package/lib/apps/push.js +510 -31
- package/lib/apps/tools.js +271 -28
- package/lib/chunk/Render-CCORwrkI.js +70 -0
- package/lib/chunk/douyin-CpQOEMNX.js +30464 -0
- package/lib/{chunk-5WIDO4V7.js → chunk/getID-WLc5wcoD.js} +1990 -2476
- package/lib/chunk/index-BDlGFCbK.js +69458 -0
- package/lib/chunk/index-BoFo2rq6.js +9131 -0
- package/lib/index.js +6164 -18
- package/lib/web.config.js +266 -210
- package/package.json +5 -10
- package/lib/chunk-DSCWGW73.js +0 -14627
- package/lib/chunk-KQITAYDY.js +0 -7
- package/lib/chunk-XHTHHTBA.js +0 -46
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# 变更日志
|
|
2
2
|
|
|
3
|
+
## [1.4.0](https://github.com/ikenxuan/karin-plugin-kkk/compare/v1.3.0...v1.4.0) (2025-05-03)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* close [#78](https://github.com/ikenxuan/karin-plugin-kkk/issues/78) ([39ae7e4](https://github.com/ikenxuan/karin-plugin-kkk/commit/39ae7e4b169c8c41fc11a8f685bf64af9d1aa9f1))
|
|
9
|
+
* close [#80](https://github.com/ikenxuan/karin-plugin-kkk/issues/80) ([f3b30b2](https://github.com/ikenxuan/karin-plugin-kkk/commit/f3b30b2b95936b1b0bae09d058f52a65a3ca3268))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* close [#74](https://github.com/ikenxuan/karin-plugin-kkk/issues/74) ([b16c890](https://github.com/ikenxuan/karin-plugin-kkk/commit/b16c8909fc1551bf54fc5945d5d44ee4cad6bfe5))
|
|
15
|
+
* close [#79](https://github.com/ikenxuan/karin-plugin-kkk/issues/79) ([41fb13b](https://github.com/ikenxuan/karin-plugin-kkk/commit/41fb13b2208c1efa1e22cd50103ab6157ea1c44f))
|
|
16
|
+
* 匹配m.douyin.com。close [#77](https://github.com/ikenxuan/karin-plugin-kkk/issues/77) ([c82c3f6](https://github.com/ikenxuan/karin-plugin-kkk/commit/c82c3f6b30f4dc0ef5588035786e3755aae2b451))
|
|
17
|
+
* 将打包工具从`tsup`迁移到`vite` 适配`node-kairn` 1.8.0 版本 ([#71](https://github.com/ikenxuan/karin-plugin-kkk/issues/71)) ([fbbc329](https://github.com/ikenxuan/karin-plugin-kkk/commit/fbbc3297fb3d1cd3b9a0a6a630f0602de8624c10))
|
|
18
|
+
|
|
3
19
|
## [1.3.0](https://github.com/ikenxuan/karin-plugin-kkk/compare/v1.2.3...v1.3.0) (2025-04-26)
|
|
4
20
|
|
|
5
21
|
|
|
@@ -13,6 +13,22 @@ numcomment: 5
|
|
|
13
13
|
# 解析视频是否优先保内容,true为优先保证上传将使用最低分辨率,false为优先保清晰度将使用最高分辨率
|
|
14
14
|
videopriority: false
|
|
15
15
|
|
|
16
|
+
# 视频画质偏好设置,0 为自动根据大小选择,其他为固定画质
|
|
17
|
+
# - 0: 自动根据大小选择
|
|
18
|
+
# - 6: 240P 极速 (仅MP4格式支持)
|
|
19
|
+
# - 16: 360P 流畅
|
|
20
|
+
# - 32: 480P 清晰
|
|
21
|
+
# - 64: 720P 高清 (WEB默认值)
|
|
22
|
+
# - 74: 720P60 高帧率 (需登录)
|
|
23
|
+
# - 80: 1080P 高清 (TV/APP默认值,需登录)
|
|
24
|
+
# - 112: 1080P+ 高码率 (需大会员)
|
|
25
|
+
# - 116: 1080P60 高帧率 (需大会员)
|
|
26
|
+
# - 120: 4K 超清 (需大会员且支持4K)
|
|
27
|
+
videoQuality: 0
|
|
28
|
+
|
|
29
|
+
# 自动画质模式下可接受的最大视频大小(单位:MB),仅在 videoQuality 为 0 时生效
|
|
30
|
+
maxAutoVideoSize: 50
|
|
31
|
+
|
|
16
32
|
# 根据「视频拦截阈值」自动选择合适的分辨率,关闭后默认选择最大分辨率进行下载
|
|
17
33
|
autoResolution: true
|
|
18
34
|
|
package/lib/Version.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import require$$7$1 from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { karinPathRoot } from "node-karin/root";
|
|
5
|
+
const pluginPath = require$$7$1.join(fileURLToPath(import.meta.url), "../..");
|
|
6
|
+
const pkg = JSON.parse(fs.readFileSync(require$$7$1.join(pluginPath, "package.json"), "utf-8"));
|
|
7
|
+
const Version = {
|
|
8
|
+
pluginName: pkg.name,
|
|
9
|
+
pluginVersion: pkg.version,
|
|
10
|
+
pluginPath,
|
|
11
|
+
karinVersion: process.env.KARIN_VERSION,
|
|
12
|
+
karinPath: karinPathRoot
|
|
13
|
+
};
|
|
14
|
+
export {
|
|
15
|
+
Version
|
|
16
|
+
};
|
package/lib/apps/admin.js
CHANGED
|
@@ -1,52 +1,206 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import path
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import karin, { handler, segment, logger } from "node-karin";
|
|
3
|
+
import require$$1 from "path";
|
|
4
|
+
import "sequelize";
|
|
5
|
+
import { d as Common, C as Config } from "../chunk/douyin-CpQOEMNX.js";
|
|
6
|
+
import { Version } from "../Version.js";
|
|
7
|
+
import "stream/promises";
|
|
8
|
+
import "node:path";
|
|
9
|
+
import { b as bilibiliLogin } from "../chunk/index-BoFo2rq6.js";
|
|
10
|
+
import "../chunk/index-BDlGFCbK.js";
|
|
11
|
+
import { execSync, spawn } from "node:child_process";
|
|
12
|
+
import { chromium } from "playwright";
|
|
13
|
+
const startXvfb = async () => {
|
|
14
|
+
if (process.platform !== "linux") return;
|
|
15
|
+
const DISPLAY_NUMBER = ":150";
|
|
16
|
+
const LOCK_FILE = "/tmp/.X150-lock";
|
|
17
|
+
try {
|
|
18
|
+
execSync(`xdpyinfo -display ${DISPLAY_NUMBER}`, { stdio: "ignore" });
|
|
19
|
+
logger.debug(`检测到 DISPLAY ${DISPLAY_NUMBER} 已经在运行,无需启动新的 Xvfb。`);
|
|
20
|
+
return;
|
|
21
|
+
} catch (err) {
|
|
22
|
+
logger.debug(logger.red(`未检测到 DISPLAY ${DISPLAY_NUMBER},尝试启动 Xvfb...`));
|
|
23
|
+
}
|
|
24
|
+
if (fs.existsSync(LOCK_FILE)) {
|
|
25
|
+
logger.debug(logger.red(`检测到锁文件 ${LOCK_FILE},可能存在冲突。尝试清理...`));
|
|
26
|
+
try {
|
|
27
|
+
fs.unlinkSync(LOCK_FILE);
|
|
28
|
+
logger.debug(`成功清理锁文件 ${LOCK_FILE}`);
|
|
29
|
+
} catch (err) {
|
|
30
|
+
logger.debug(logger.red(`无法清理锁文件 ${LOCK_FILE},请检查权限或手动处理。`));
|
|
31
|
+
throw err;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const xvfb = spawn("Xvfb", [DISPLAY_NUMBER, "-ac", "-screen", "0", "1280x1024x24"], {
|
|
35
|
+
stdio: "inherit"
|
|
36
|
+
});
|
|
37
|
+
xvfb.unref();
|
|
38
|
+
process.env.DISPLAY = DISPLAY_NUMBER;
|
|
39
|
+
let retries = 5;
|
|
40
|
+
while (retries > 0) {
|
|
41
|
+
try {
|
|
42
|
+
execSync(`xdpyinfo -display ${DISPLAY_NUMBER}`, { stdio: "ignore" });
|
|
43
|
+
logger.debug(`Xvfb (${DISPLAY_NUMBER}) 启动成功`);
|
|
44
|
+
return;
|
|
45
|
+
} catch (err) {
|
|
46
|
+
logger.debug(logger.yellow(`Xvfb (${DISPLAY_NUMBER}) 启动失败,正在重试...`));
|
|
47
|
+
retries -= 1;
|
|
48
|
+
if (retries > 0) {
|
|
49
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
50
|
+
} else {
|
|
51
|
+
logger.debug(logger.red("Xvfb 启动失败,重试多次后仍未成功"));
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const douyinLogin = async (e) => {
|
|
58
|
+
const hal = await handler.call("kkk.douyinLogin", { e });
|
|
59
|
+
if (hal) return true;
|
|
60
|
+
const msg_id = [];
|
|
61
|
+
const message1 = await e.reply("免责声明:\n您将通过扫码完成获取抖音网页端的用户登录凭证(ck),该ck将用于请求抖音WEB API接口。\n本BOT不会上传任何有关你的信息到第三方,所配置的 ck 只会用于请求官方 API 接口。\n我方仅提供视频解析及相关抖音内容服务,若您的账号封禁、被盗等处罚与我方无关。\n害怕风险请勿扫码 ~");
|
|
62
|
+
try {
|
|
63
|
+
startXvfb();
|
|
64
|
+
const browser = await chromium.launch({
|
|
65
|
+
headless: false,
|
|
66
|
+
args: [
|
|
67
|
+
"--disable-blink-features=AutomationControlled",
|
|
68
|
+
// 禁用自动化控制
|
|
69
|
+
"--window-position=-10000,-10000",
|
|
70
|
+
// 将窗口移到屏幕外
|
|
71
|
+
"--start-minimized",
|
|
72
|
+
// 启动时最小化
|
|
73
|
+
"--mute-audio",
|
|
74
|
+
// 静音
|
|
75
|
+
"--no-sandbox"
|
|
76
|
+
// 使用无沙箱模式,适合无桌面环境
|
|
77
|
+
]
|
|
78
|
+
});
|
|
79
|
+
const page = await browser.newPage();
|
|
80
|
+
await page.goto("https://www.douyin.com", { timeout: 12e4 });
|
|
81
|
+
const timeout = new Promise((resolve) => setTimeout(async () => {
|
|
82
|
+
await browser.close();
|
|
83
|
+
}, 12e4));
|
|
84
|
+
const qrCodePromise = (async () => {
|
|
85
|
+
try {
|
|
86
|
+
const qrCodeBase64 = await waitQrcode(page);
|
|
87
|
+
const base64Data = qrCodeBase64 ? qrCodeBase64.replace(/^data:image\/\w+;base64,/, "") : "";
|
|
88
|
+
const buffer = Buffer.from(base64Data, "base64");
|
|
89
|
+
fs.writeFileSync(`${Common.tempDri.default}DouyinLoginQrcode.png`, buffer);
|
|
90
|
+
const message2 = await e.reply([segment.image("base64://" + base64Data), segment.text("请在120秒内通过抖音APP扫码进行登录")], { reply: true });
|
|
91
|
+
msg_id.push(message2.messageId, message1.messageId);
|
|
92
|
+
page.on("response", async (response) => {
|
|
93
|
+
try {
|
|
94
|
+
logger.debug(`接收到响应:${response.url()}`);
|
|
95
|
+
if (response.status() === 302 && response.url().includes("/passport/sso/login/callback")) {
|
|
96
|
+
const localCookies = await page.context().cookies();
|
|
97
|
+
const cookieString = localCookies.map((cookie) => `${cookie.name}=${cookie.value}`).join("; ");
|
|
98
|
+
Config.Modify("cookies", "douyin", cookieString);
|
|
99
|
+
await e.reply("登录成功!用户登录凭证已保存至cookies.yaml", { reply: true });
|
|
100
|
+
await browser.close();
|
|
101
|
+
await Promise.all(msg_id.map(async (id) => {
|
|
102
|
+
await e.bot.recallMsg(e.contact, id);
|
|
103
|
+
}));
|
|
104
|
+
} else if (response.headers()["content-type"] && response.headers()["content-type"].includes("application/json") && response.url().includes("https://sso.douyin.com")) {
|
|
105
|
+
const responseBody = await response.body();
|
|
106
|
+
const jsonResponse = JSON.parse(responseBody.toString());
|
|
107
|
+
logger.debug(`SSO 回调 Code:${jsonResponse.error_code}`, `响应内容:${jsonResponse.description}`);
|
|
108
|
+
if (jsonResponse.error_code === 2046) {
|
|
109
|
+
logger.debug("需要短信验证码");
|
|
110
|
+
await page.getByText("接收短信验证").click();
|
|
111
|
+
const elements = page.locator(":has-text('为保护账号安全,请输入当前手机号')");
|
|
112
|
+
const texts = await elements.allInnerTexts();
|
|
113
|
+
await page.getByText("获取验证码").click();
|
|
114
|
+
const message3 = await e.reply(segment.text(texts.pop()));
|
|
115
|
+
msg_id.push(message3.messageId);
|
|
116
|
+
const ctx = await karin.ctx(e, { reply: true });
|
|
117
|
+
await page.getByPlaceholder("请输入验证码").click();
|
|
118
|
+
await page.getByPlaceholder("请输入验证码").fill(ctx.msg);
|
|
119
|
+
await page.getByText("验证", { exact: true }).click();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} catch (error) {
|
|
123
|
+
await browser.close();
|
|
124
|
+
await Promise.all(msg_id.map(async (id) => {
|
|
125
|
+
await e.bot.recallMsg(e.contact, id);
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
} catch (error) {
|
|
130
|
+
await browser.close();
|
|
131
|
+
await Promise.all(msg_id.map(async (id) => {
|
|
132
|
+
await e.bot.recallMsg(e.contact, id);
|
|
133
|
+
}));
|
|
134
|
+
await e.reply("登录超时!二维码已失效!", { reply: true });
|
|
135
|
+
logger.error(error);
|
|
136
|
+
}
|
|
137
|
+
})();
|
|
138
|
+
await Promise.race([qrCodePromise, timeout]);
|
|
139
|
+
} catch (error) {
|
|
140
|
+
logger.error(error);
|
|
141
|
+
if (error.message.includes("npx playwright install")) {
|
|
142
|
+
const msg = await e.reply("首次使用,正在初始化 playwright 环境,请稍等片刻...");
|
|
143
|
+
execSync("npx playwright install chromium", { cwd: Version.pluginPath, stdio: "inherit" });
|
|
144
|
+
await e.reply(`playwright 初始化成功,请再次发送「${e.msg}」`);
|
|
145
|
+
await e.bot.recallMsg(e.contact, msg.messageId);
|
|
146
|
+
return true;
|
|
147
|
+
} else {
|
|
148
|
+
await e.reply("chromiun 环境初始化失败,请查看控制台错误日志", { reply: true });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return true;
|
|
152
|
+
};
|
|
153
|
+
const waitQrcode = async (page) => {
|
|
154
|
+
const qrCodeSelector = ".web-login-scan-code__content__qrcode-wrapper img";
|
|
155
|
+
const loginButton = page.getByRole("button", { name: "登录" });
|
|
156
|
+
const qrCodeImage = await page.waitForSelector(qrCodeSelector, { state: "attached", timeout: 3e4 });
|
|
157
|
+
if (qrCodeImage) {
|
|
158
|
+
const qrCodeBase64 = await qrCodeImage.getAttribute("src");
|
|
159
|
+
return qrCodeBase64;
|
|
160
|
+
} else {
|
|
161
|
+
await loginButton.click();
|
|
162
|
+
await page.waitForSelector(qrCodeSelector, { timeout: 2e4 });
|
|
163
|
+
const qrCodeImage2 = await page.waitForSelector(qrCodeSelector, { timeout: 2e4 });
|
|
164
|
+
const qrCodeBase64 = await qrCodeImage2.getAttribute("src");
|
|
165
|
+
return qrCodeBase64;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const task = Config.app.rmmp4 && karin.task("[kkk-视频缓存自动删除]", "0 0 4 * * *", async () => {
|
|
15
169
|
try {
|
|
16
170
|
await removeAllFiles(Common.tempDri.video);
|
|
17
|
-
logger.mark(Common.tempDri.video + "
|
|
171
|
+
logger.mark(Common.tempDri.video + "目录下所有文件已删除");
|
|
18
172
|
} catch (err) {
|
|
19
|
-
console.error("
|
|
173
|
+
console.error("删除文件时出错:", err);
|
|
20
174
|
}
|
|
21
175
|
});
|
|
22
|
-
|
|
176
|
+
const biLogin = karin.command(/^#?(kkk)?\s*B站\s*(扫码)?\s*登录$/i, async (e) => {
|
|
23
177
|
await bilibiliLogin(e);
|
|
24
178
|
return true;
|
|
25
|
-
}, { perm: Config.bilibili.loginPerm, name: "kkk-ck
|
|
26
|
-
|
|
179
|
+
}, { perm: Config.bilibili.loginPerm, name: "kkk-ck管理" });
|
|
180
|
+
const dylogin = karin.command(/^#?(kkk)?抖音(扫码)?登录$/, async (e) => {
|
|
27
181
|
await douyinLogin(e);
|
|
28
182
|
return true;
|
|
29
|
-
}, { perm: Config.douyin.loginPerm, name: "kkk-ck
|
|
30
|
-
|
|
31
|
-
const msg = await e.reply("\
|
|
183
|
+
}, { perm: Config.douyin.loginPerm, name: "kkk-ck管理" });
|
|
184
|
+
const setdyck = karin.command(/^#?(kkk)?s*设置抖音ck$/i, async (e) => {
|
|
185
|
+
const msg = await e.reply("请发在120秒内送抖音ck\n教程:https://ikenxuan.github.io/kkkkkk-10086/docs/intro/other#%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%90%8C%E5%B9%B3%E5%8F%B0%E7%9A%84-cookies\n");
|
|
32
186
|
const context = await karin.ctx(e);
|
|
33
187
|
Config.Modify("cookies", "douyin", context.msg);
|
|
34
188
|
await e.bot.recallMsg(e.contact, msg.messageId);
|
|
35
|
-
await e.reply("
|
|
189
|
+
await e.reply("设置成功!", { at: true });
|
|
36
190
|
return true;
|
|
37
|
-
}, { perm: "master", name: "kkk-ck
|
|
38
|
-
|
|
39
|
-
const msg = await e.reply("\
|
|
191
|
+
}, { perm: "master", name: "kkk-ck管理", event: "message.friend" });
|
|
192
|
+
const setbilick = karin.command(/^#?(kkk)?s*设置s*(B站)ck$/i, async (e) => {
|
|
193
|
+
const msg = await e.reply("请发在120秒内送B站ck\n教程:https://ikenxuan.github.io/kkkkkk-10086/docs/intro/other#%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%90%8C%E5%B9%B3%E5%8F%B0%E7%9A%84-cookies\n");
|
|
40
194
|
const context = await karin.ctx(e);
|
|
41
195
|
Config.Modify("cookies", "bilibili", context.msg);
|
|
42
196
|
await e.bot.recallMsg(e.contact, msg.messageId);
|
|
43
|
-
await e.reply("
|
|
197
|
+
await e.reply("设置成功!", { at: true });
|
|
44
198
|
return true;
|
|
45
|
-
}, { perm: "master", name: "kkk-ck
|
|
199
|
+
}, { perm: "master", name: "kkk-ck管理", event: "message.friend" });
|
|
46
200
|
async function removeAllFiles(dir) {
|
|
47
201
|
const files = await fs.promises.readdir(dir);
|
|
48
202
|
for (const file of files) {
|
|
49
|
-
const filePath =
|
|
203
|
+
const filePath = require$$1.join(dir, file);
|
|
50
204
|
const stats = await fs.promises.stat(filePath);
|
|
51
205
|
if (stats.isDirectory()) {
|
|
52
206
|
await removeAllFiles(filePath);
|
|
@@ -56,5 +210,10 @@ async function removeAllFiles(dir) {
|
|
|
56
210
|
}
|
|
57
211
|
}
|
|
58
212
|
}
|
|
59
|
-
|
|
60
|
-
|
|
213
|
+
export {
|
|
214
|
+
biLogin,
|
|
215
|
+
dylogin,
|
|
216
|
+
setbilick,
|
|
217
|
+
setdyck,
|
|
218
|
+
task
|
|
219
|
+
};
|
package/lib/apps/help.js
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// src/apps/help.ts
|
|
13
|
-
init_esm_shims();
|
|
14
|
-
var help = karin.command(/^#?kkk帮助$/, async (e) => {
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import { m as markdown } from "../chunk/index-BDlGFCbK.js";
|
|
4
|
+
import karin, { mkdirSync, render, segment, isPackaged, updatePkg, updateGitPlugin, logger, common, restart } from "node-karin";
|
|
5
|
+
import { karinPathTemp } from "node-karin/root";
|
|
6
|
+
import "sequelize";
|
|
7
|
+
import { C as Config, d as Common } from "../chunk/douyin-CpQOEMNX.js";
|
|
8
|
+
import { Version } from "../Version.js";
|
|
9
|
+
import "stream/promises";
|
|
10
|
+
import { R as Render } from "../chunk/Render-CCORwrkI.js";
|
|
11
|
+
const help = karin.command(/^#?kkk帮助$/, async (e) => {
|
|
15
12
|
const img = await Render("help/index");
|
|
16
13
|
await e.reply(img);
|
|
17
14
|
return true;
|
|
18
|
-
}, { name: "kkk
|
|
19
|
-
|
|
15
|
+
}, { name: "kkk-帮助" });
|
|
16
|
+
const version = karin.command(/^#?kkk版本$/, async (e) => {
|
|
20
17
|
Config.douyin.push.switch = false;
|
|
21
18
|
const changelogs2 = fs.readFileSync(Version.pluginPath + "/CHANGELOG.md", "utf8");
|
|
22
19
|
const html = markdown(changelogs2, {
|
|
@@ -28,8 +25,8 @@ var version = karin.command(/^#?kkk版本$/, async (e) => {
|
|
|
28
25
|
const img = await render.renderHtml(htmlPath);
|
|
29
26
|
await e.reply(segment.image("base64://" + img));
|
|
30
27
|
return true;
|
|
31
|
-
}, { name: "kkk
|
|
32
|
-
|
|
28
|
+
}, { name: "kkk-版本" });
|
|
29
|
+
const changelogs = karin.command(/^#?kkk更新日志$/, async (e) => {
|
|
33
30
|
const commits = getLatestCommitsSync();
|
|
34
31
|
let htmlString = "";
|
|
35
32
|
for (const commit of commits) {
|
|
@@ -50,12 +47,12 @@ var changelogs = karin.command(/^#?kkk更新日志$/, async (e) => {
|
|
|
50
47
|
const img = await render.renderHtml(htmlPath);
|
|
51
48
|
await e.reply(segment.image("base64://" + img));
|
|
52
49
|
return true;
|
|
53
|
-
}, { name: "kkk
|
|
54
|
-
|
|
50
|
+
}, { name: "kkk-更新日志" });
|
|
51
|
+
const update = karin.command(/^#?kkk更新(预览版)?$/, async (e) => {
|
|
55
52
|
let status = "failed";
|
|
56
53
|
let data = "";
|
|
57
54
|
if (isPackaged) {
|
|
58
|
-
if (e.msg.includes("
|
|
55
|
+
if (e.msg.includes("预览版")) {
|
|
59
56
|
const resolve = await updatePkg(Version.pluginName, "beta");
|
|
60
57
|
status = resolve.status;
|
|
61
58
|
data = resolve.data;
|
|
@@ -66,7 +63,7 @@ var update = karin.command(/^#?kkk更新(预览版)?$/, async (e) => {
|
|
|
66
63
|
}
|
|
67
64
|
} else {
|
|
68
65
|
let cmd = "git pull";
|
|
69
|
-
if (e.msg.includes("
|
|
66
|
+
if (e.msg.includes("强制")) {
|
|
70
67
|
cmd = "git reset --hard && git pull --allow-unrelated-histories";
|
|
71
68
|
}
|
|
72
69
|
const resolve = await updateGitPlugin(Version.pluginPath, cmd);
|
|
@@ -74,21 +71,21 @@ var update = karin.command(/^#?kkk更新(预览版)?$/, async (e) => {
|
|
|
74
71
|
data = resolve.data;
|
|
75
72
|
}
|
|
76
73
|
logger.debug(data);
|
|
77
|
-
await e.bot.sendForwardMsg(e.contact, common.makeForward([segment.text(
|
|
74
|
+
await e.bot.sendForwardMsg(e.contact, common.makeForward([segment.text(`更新 ${Version.pluginName}...
|
|
78
75
|
${JSON.stringify(data)}`)], e.sender.userId, e.sender.nick));
|
|
79
76
|
if (status === "ok") {
|
|
80
77
|
try {
|
|
81
78
|
await e.reply(`
|
|
82
|
-
|
|
79
|
+
更新完成,开始重启 本次运行时间:${common.uptime()}`, { at: true });
|
|
83
80
|
await restart(e.selfId, e.contact, e.messageId);
|
|
84
81
|
return true;
|
|
85
82
|
} catch (error) {
|
|
86
|
-
await e.reply(`${Version.pluginName}
|
|
83
|
+
await e.reply(`${Version.pluginName}重启失败,请手动重启以应用更新!`);
|
|
87
84
|
}
|
|
88
85
|
}
|
|
89
86
|
return true;
|
|
90
|
-
}, { name: "kkk
|
|
91
|
-
|
|
87
|
+
}, { name: "kkk-更新", perm: "master" });
|
|
88
|
+
const getLatestCommitsSync = () => {
|
|
92
89
|
const command = 'git log -150 --pretty=format:"%h %an %s"';
|
|
93
90
|
const output = execSync(command, { cwd: Version.pluginPath }).toString();
|
|
94
91
|
const commits = output.trim().split("\n");
|
|
@@ -101,7 +98,7 @@ var getLatestCommitsSync = () => {
|
|
|
101
98
|
return { sha, committer, message };
|
|
102
99
|
}).slice(0, 50);
|
|
103
100
|
};
|
|
104
|
-
|
|
101
|
+
const setColor = (message) => {
|
|
105
102
|
switch (true) {
|
|
106
103
|
case message.includes("feat"):
|
|
107
104
|
return "10px solid #a9ffb9";
|
|
@@ -115,5 +112,9 @@ var setColor = (message) => {
|
|
|
115
112
|
return "2px solid";
|
|
116
113
|
}
|
|
117
114
|
};
|
|
118
|
-
|
|
119
|
-
|
|
115
|
+
export {
|
|
116
|
+
changelogs,
|
|
117
|
+
help,
|
|
118
|
+
update,
|
|
119
|
+
version
|
|
120
|
+
};
|