karin-plugin-kkk 1.1.0 → 1.1.1

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.1.1](https://github.com/ikenxuan/karin-plugin-kkk/compare/v1.1.0...v1.1.1) (2025-02-24)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * fix [#41](https://github.com/ikenxuan/karin-plugin-kkk/issues/41) ([6335eea](https://github.com/ikenxuan/karin-plugin-kkk/commit/6335eeabaa59ca188473be191251f16c30ee4970))
9
+ * save web config ([c594c0c](https://github.com/ikenxuan/karin-plugin-kkk/commit/c594c0c800abd8dff97c7af1d3f4dd175d068792))
10
+ * 选择性记录 ([89f9e1b](https://github.com/ikenxuan/karin-plugin-kkk/commit/89f9e1b791eb257f40965fdaccf132ba210e5758))
11
+
12
+
13
+ ### Performance Improvements
14
+
15
+ * web config ([24c9dd0](https://github.com/ikenxuan/karin-plugin-kkk/commit/24c9dd0d1e0591633565d4c05c26bc385aba2c0b))
16
+
3
17
  ## [1.1.0](https://github.com/ikenxuan/karin-plugin-kkk/compare/v1.0.9...v1.1.0) (2025-02-22)
4
18
 
5
19
 
package/lib/index.js CHANGED
@@ -14,7 +14,7 @@ server.use(cors());
14
14
  server.use('/', createProxyMiddleware(proxyOptions));
15
15
  server.listen(3780);
16
16
  if (Config.app.APIServer && Config.app.APIServerMount) {
17
- app.use(logMiddleware);
17
+ app.use(logMiddleware(['/api/bilibili', '/api/douyin', '/api/kuaishou']));
18
18
  app.use('/api/bilibili', registerBilibiliRoutes(Config.cookies.bilibili));
19
19
  app.use('/api/douyin', registerDouyinRoutes(Config.cookies.douyin));
20
20
  app.use('/api/kuaishou', registerKuaishouRoutes(Config.cookies.kuaishou));
@@ -160,8 +160,8 @@ export class Base {
160
160
  function generateProgressBar(progressPercentage) {
161
161
  const filledLength = Math.floor((progressPercentage / 100) * barLength);
162
162
  let progress = '';
163
- progress += '#'.repeat(filledLength);
164
- progress += '-'.repeat(Math.max(0, barLength - filledLength - 1));
163
+ progress += '\u2588'.repeat(filledLength);
164
+ progress += '\u2591'.repeat(Math.max(0, barLength - filledLength - 1));
165
165
  return `[${progress}]`;
166
166
  }
167
167
  // 计算当前下载进度百分比
@@ -183,7 +183,7 @@ export class Base {
183
183
  const downloadedSizeMB = (downloadedBytes / 1048576).toFixed(1);
184
184
  const totalSizeMB = (totalBytes / 1048576).toFixed(1);
185
185
  // 打印下载进度、速度和剩余时间
186
- console.log(`🚀 Downloading 🚀 ${opt.title} ${generateProgressBar(progressPercentage)} ${coloredPercentage} ${downloadedSizeMB}/${totalSizeMB} MB | ${formattedSpeed} 剩余: ${formattedRemainingTime}\r`);
186
+ console.log(`⬇️ ${opt.title} ${generateProgressBar(progressPercentage)} ${coloredPercentage} ${downloadedSizeMB}/${totalSizeMB} MB | ${formattedSpeed} 剩余: ${formattedRemainingTime}\r`);
187
187
  }, 3);
188
188
  return { filepath, totalBytes };
189
189
  }
@@ -1,3 +1,4 @@
1
+ import { BiliBangumiVideoInfo, BiliBangumiVideoPlayurlIsLogin, BiliBangumiVideoPlayurlNoLogin, BiliBiliVideoPlayurlNoLogin, BiliOneWork, BiliVideoPlayurlIsLogin } from '@ikenxuan/amagi';
1
2
  import { Message } from 'node-karin';
2
3
  import { Base } from '../../module/utils/index.js';
3
4
  import { BilibiliId } from '../../platform/bilibili/index.js';
@@ -23,7 +24,10 @@ export declare class Bilibili extends Base {
23
24
  get botadapter(): string;
24
25
  constructor(e: Message, data: any);
25
26
  RESOURCES(iddata: BilibiliId): Promise<boolean | undefined>;
26
- getvideo({ infoData, playUrlData }: any): Promise<void>;
27
+ getvideo({ infoData, playUrlData }: {
28
+ infoData?: BiliBangumiVideoInfo | BiliOneWork;
29
+ playUrlData: BiliVideoPlayurlIsLogin | BiliBiliVideoPlayurlNoLogin | BiliBangumiVideoPlayurlIsLogin | BiliBangumiVideoPlayurlNoLogin;
30
+ }): Promise<void>;
27
31
  getvideosize(videourl: any, audiourl: any, bvid: any): Promise<string>;
28
32
  /**
29
33
  * 检出应该下载的视频流
@@ -176,18 +176,14 @@ export class Bilibili extends Base {
176
176
  playUrlData.result.dash.video = correctList.videoList;
177
177
  playUrlData.result.cept_description = correctList.accept_description;
178
178
  await this.getvideo({
179
- videoInfo,
180
- playUrlData,
181
- video_url: playUrlData.result.dash.video[0].base_url,
182
- audio_url: playUrlData.result.dash.audio[0].base_url
179
+ infoData: videoInfo,
180
+ playUrlData
183
181
  });
184
182
  }
185
183
  else {
186
184
  await this.getvideo({
187
- videoInfo,
188
- playUrlData,
189
- video_url: playUrlData.result.dash.video[0].base_url,
190
- audio_url: playUrlData.result.dash.audio[0].base_url
185
+ infoData: videoInfo,
186
+ playUrlData
191
187
  });
192
188
  }
193
189
  break;
@@ -452,19 +448,19 @@ export class Bilibili extends Base {
452
448
  }
453
449
  switch (this.islogin) {
454
450
  case true: {
455
- const bmp4 = await this.DownLoadFile(this.Type === 'one_video' ? playUrlData.data?.dash?.video[0].base_url : playUrlData.video_url, {
456
- title: `Bil_V_${this.Type === 'one_video' ? infoData.data.bvid : infoData.result.season_id}.mp4`,
451
+ const bmp4 = await this.DownLoadFile(this.Type === 'one_video' ? playUrlData.data?.dash?.video[0].base_url : playUrlData.result.dash.video[0].base_url, {
452
+ title: `Bil_V_${this.Type === 'one_video' ? infoData && infoData.data.bvid : infoData && infoData.result.season_id}.mp4`,
457
453
  headers: this.headers
458
454
  });
459
- const bmp3 = await this.DownLoadFile(this.Type === 'one_video' ? playUrlData.data?.dash?.audio[0].base_url : playUrlData.audio_url, {
460
- title: `Bil_A_${this.Type === 'one_video' ? infoData.data.bvid : infoData.result.season_id}.mp3`,
455
+ const bmp3 = await this.DownLoadFile(this.Type === 'one_video' ? playUrlData.data?.dash?.audio[0].base_url : playUrlData.result.dash.audio[0].base_url, {
456
+ title: `Bil_A_${this.Type === 'one_video' ? infoData && infoData.data.bvid : infoData && infoData.result.season_id}.mp3`,
461
457
  headers: this.headers
462
458
  });
463
459
  if (bmp4.filepath && bmp3.filepath) {
464
460
  await mergeFile('二合一(视频 + 音频)', {
465
461
  path: bmp4.filepath,
466
462
  path2: bmp3.filepath,
467
- resultPath: Common.tempDri.video + `Bil_Result_${this.Type === 'one_video' ? infoData.data.bvid : infoData.result.season_id}.mp4`,
463
+ resultPath: Common.tempDri.video + `Bil_Result_${this.Type === 'one_video' ? infoData && infoData.data.bvid : infoData && infoData.result.season_id}.mp4`,
468
464
  callback: async (success, resultPath) => {
469
465
  if (success) {
470
466
  const filePath = Common.tempDri.video + `${Config.app.rmmp4 ? 'tmp_' + Date.now() : this.downloadfilename}.mp4`;
@@ -16,7 +16,7 @@ export function bilibiliComments(commentsData) {
16
16
  const vipstatus = commentsData.data.replies[i].member.vip.status;
17
17
  const like = commentsData.data.replies[i].like;
18
18
  const replylength = commentsData.data.replies[i].rcount;
19
- const location = commentsData.data.replies[i].reply_control.location;
19
+ const location = commentsData.data.replies[i].reply_control.location.replace('IP属地:', '');
20
20
  const img_src = commentsData.data.replies[i].content &&
21
21
  commentsData.data.replies[i].content.pictures &&
22
22
  commentsData.data.replies[i].content.pictures.length > 0
@@ -1,9 +1,12 @@
1
+ import { ConfigType } from './types/index.js';
1
2
  declare const _default: {
2
3
  info: {};
3
4
  /** 动态渲染的组件 */
4
5
  components: () => (import("node-karin").DividerProps | import("node-karin").AccordionProps | import("node-karin").AccordionProProps)[];
5
6
  /** 前端点击保存之后调用的方法 */
6
7
  save: (config: any) => {
8
+ fullData: ConfigType;
9
+ formatCfg: ConfigType;
7
10
  success: boolean;
8
11
  message: string;
9
12
  };
package/lib/web.config.js CHANGED
@@ -17,29 +17,32 @@ export default {
17
17
  className: 'ml-4 mr-4',
18
18
  subtitle: '建议配置,否则大部分功能无法使用',
19
19
  children: [
20
- components.input.string('cfg.cookies.douyin', {
20
+ components.input.string('douyin', {
21
21
  label: '抖音',
22
22
  type: 'text',
23
23
  description: '请输入你的抖音Cookies,不输入则无法使用抖音相关功能噢',
24
24
  defaultValue: all.cookies.douyin,
25
25
  placeholder: '',
26
- rules: undefined
26
+ rules: undefined,
27
+ isRequired: false
27
28
  }),
28
- components.input.string('cfg.cookies.bilibili', {
29
+ components.input.string('bilibili', {
29
30
  label: 'B站',
30
31
  type: 'text',
31
32
  description: '请输入你的B站Cookies,不输入则无法使用B站相关功能噢',
32
33
  defaultValue: all.cookies.bilibili,
33
34
  placeholder: '',
34
- rules: undefined
35
+ rules: undefined,
36
+ isRequired: false
35
37
  }),
36
- components.input.string('cfg.cookies.kuaishou', {
38
+ components.input.string('kuaishou', {
37
39
  label: '快手',
38
40
  type: 'text',
39
41
  description: '请输入你的快手Cookies,不输入则无法使用快手相关功能噢',
40
42
  defaultValue: all.cookies.kuaishou,
41
43
  placeholder: '',
42
- rules: undefined
44
+ rules: undefined,
45
+ isRequired: false
43
46
  })
44
47
  ]
45
48
  })
@@ -56,24 +59,24 @@ export default {
56
59
  className: 'ml-4 mr-4',
57
60
  subtitle: '此处用于管理插件的基本设置',
58
61
  children: [
59
- components.switch.create('cfg.app.rmmp4', {
62
+ components.switch.create('rmmp4', {
60
63
  startText: '缓存删除',
61
64
  description: '缓存自动删除,非必要不修改!',
62
65
  defaultSelected: all.app.rmmp4
63
66
  }),
64
- components.switch.create('cfg.app.defaulttool', {
67
+ components.switch.create('defaulttool', {
65
68
  startText: '默认解析',
66
69
  description: '即识别最高优先级,修改后重启生效',
67
70
  defaultSelected: all.app.defaulttool
68
71
  }),
69
- components.input.number('cfg.app.priority', {
72
+ components.input.number('priority', {
70
73
  label: '自定义优先级',
71
74
  description: '自定义优先级,「默认解析」关闭后才会生效。修改后重启生效',
72
75
  defaultValue: all.app.priority.toString(),
73
76
  isDisabled: all.app.defaulttool,
74
77
  rules: undefined
75
78
  }),
76
- components.input.number('cfg.app.renderScale', {
79
+ components.input.number('renderScale', {
77
80
  label: '渲染精度',
78
81
  description: '可选值50~200,建议100。设置高精度会提高图片的精细度,过高可能会影响渲染与发送速度',
79
82
  defaultValue: all.app.renderScale.toString(),
@@ -84,17 +87,17 @@ export default {
84
87
  }
85
88
  ]
86
89
  }),
87
- components.switch.create('cfg.app.APIServer', {
90
+ components.switch.create('APIServer', {
88
91
  startText: 'API服务',
89
92
  description: '本地部署一个视频解析API服务,接口范围为本插件用到的所有',
90
93
  defaultSelected: all.app.APIServer
91
94
  }),
92
- components.switch.create('cfg.app.APIServerMount', {
95
+ components.switch.create('APIServerMount', {
93
96
  startText: '挂载到 Karin',
94
97
  description: 'API 服务是否挂载到 Karin 上,开启后监听端口为 Karin 的 http 端口,修改后需重启',
95
98
  defaultSelected: all.app.APIServerMount
96
99
  }),
97
- components.input.number('cfg.app.APIServerPort', {
100
+ components.input.number('APIServerPort', {
98
101
  label: 'API服务端口',
99
102
  defaultValue: all.app.APIServerPort.toString(),
100
103
  isDisabled: all.app.APIServerMount,
@@ -106,20 +109,20 @@ export default {
106
109
  }
107
110
  ]
108
111
  }),
109
- components.radio.group('cfg.app.Theme', {
112
+ components.radio.group('Theme', {
110
113
  label: '渲染图片的主题色',
111
114
  orientation: 'horizontal',
112
115
  defaultValue: all.app.Theme.toString(),
113
116
  radio: [
114
- components.radio.create('cfg.app.Theme-1', {
117
+ components.radio.create('Theme-1', {
115
118
  label: '自动',
116
119
  value: '0'
117
120
  }),
118
- components.radio.create('cfg.app.Theme-2', {
121
+ components.radio.create('Theme-2', {
119
122
  label: '浅色',
120
123
  value: '1'
121
124
  }),
122
- components.radio.create('cfg.app.Theme-3', {
125
+ components.radio.create('Theme-3', {
123
126
  label: '深色',
124
127
  value: '2'
125
128
  })
@@ -140,27 +143,27 @@ export default {
140
143
  className: 'ml-4 mr-4',
141
144
  subtitle: '此处为抖音相关的用户偏好设置',
142
145
  children: [
143
- components.switch.create('cfg.douyin.switch', {
146
+ components.switch.create('switch', {
144
147
  startText: '解析开关',
145
148
  description: '抖音解析开关,此开关为单独开关',
146
149
  defaultSelected: all.douyin.switch
147
150
  }),
148
- components.switch.create('cfg.douyin.tip', {
151
+ components.switch.create('tip', {
149
152
  startText: '解析提示',
150
153
  description: '抖音解析提示,发送提示信息:“检测到抖音链接,开始解析”',
151
154
  defaultSelected: all.douyin.tip
152
155
  }),
153
- components.switch.create('cfg.douyin.comment', {
156
+ components.switch.create('comment', {
154
157
  startText: '评论解析',
155
158
  description: '抖音评论解析,开启后可发送抖音作品评论图',
156
159
  defaultSelected: all.douyin.comment
157
160
  }),
158
- components.input.number('cfg.douyin.numcomment', {
161
+ components.input.number('numcomment', {
159
162
  label: '评论解析数量',
160
163
  defaultValue: all.douyin.numcomment.toString(),
161
164
  rules: [{ min: 1 }]
162
165
  }),
163
- components.switch.create('cfg.douyin.autoResolution', {
166
+ components.switch.create('autoResolution', {
164
167
  startText: '自动分辨率',
165
168
  description: '根据「视频拦截阈值」自动选择合适的分辨率,关闭后默认选择最大分辨率进行下载',
166
169
  defaultSelected: all.douyin.autoResolution
@@ -169,70 +172,70 @@ export default {
169
172
  description: '抖音推送相关',
170
173
  descPosition: 20
171
174
  }),
172
- components.switch.create('cfg.douyin.push.switch', {
175
+ components.switch.create('push.switch', {
173
176
  startText: '推送开关',
174
177
  description: '推送开关,开启后需重启;使用「#设置抖音推送 + 抖音号」配置推送列表',
175
178
  defaultSelected: all.douyin.push.switch
176
179
  }),
177
- components.input.group('cfg.douyin.push.banWords', {
180
+ components.input.group('push.banWords', {
178
181
  label: '作品中有以下指定关键词时,不推送',
179
182
  maxRows: 2,
180
183
  itemsPerRow: 4,
181
184
  data: all.douyin.push.banWords,
182
- template: components.input.string('cfg.douyin.push.banWords', {
185
+ template: components.input.string('push.banWords', {
183
186
  placeholder: '',
184
187
  label: '',
185
188
  color: 'success'
186
189
  })
187
190
  }),
188
- components.input.group('cfg.douyin.push.banTags', {
191
+ components.input.group('push.banTags', {
189
192
  label: '作品中有指定标签时,不推送',
190
193
  maxRows: 2,
191
194
  itemsPerRow: 4,
192
195
  data: all.douyin.push.banWords,
193
- template: components.input.string('cfg.douyin.push.banTags', {
196
+ template: components.input.string('push.banTags', {
194
197
  placeholder: '',
195
198
  label: '',
196
199
  color: 'success'
197
200
  })
198
201
  }),
199
- components.radio.group('cfg.douyin.push.permission', {
202
+ components.radio.group('push.permission', {
200
203
  label: '谁可以设置推送',
201
204
  orientation: 'horizontal',
202
205
  defaultValue: all.douyin.push.permission,
203
206
  radio: [
204
- components.radio.create('cfg.douyin.push.permission.radio-1', {
207
+ components.radio.create('push.permission.radio-1', {
205
208
  label: '所有人',
206
209
  value: 'all'
207
210
  }),
208
- components.radio.create('cfg.douyin.push.permission.radio-2', {
211
+ components.radio.create('push.permission.radio-2', {
209
212
  label: '管理员',
210
213
  value: 'admin'
211
214
  }),
212
- components.radio.create('cfg.douyin.push.permission.radio-3', {
215
+ components.radio.create('push.permission.radio-3', {
213
216
  label: '主人',
214
217
  value: 'master'
215
218
  }),
216
- components.radio.create('cfg.douyin.push.permission.radio-4', {
219
+ components.radio.create('push.permission.radio-4', {
217
220
  label: '群主',
218
221
  value: 'group.owner'
219
222
  }),
220
- components.radio.create('cfg.douyin.push.permission.radio-5', {
223
+ components.radio.create('push.permission.radio-5', {
221
224
  label: '群管理员',
222
225
  value: 'group.admin'
223
226
  })
224
227
  ]
225
228
  }),
226
- components.input.string('cfg.douyin.push.cron', {
229
+ components.input.string('push.cron', {
227
230
  label: '定时任务表达式',
228
231
  defaultValue: all.douyin.push.cron
229
232
  }),
230
- components.switch.create('cfg.douyin.push.parsedynamic', {
233
+ components.switch.create('push.parsedynamic', {
231
234
  startText: '作品解析',
232
235
  description: '触发推送时是否一同解析该作品',
233
236
  defaultSelected: all.douyin.push.parsedynamic
234
237
  }),
235
- components.switch.create('cfg.douyin.push.log', {
238
+ components.switch.create('push.log', {
236
239
  startText: '推送日志',
237
240
  description: '是否打印推送日志(修改后需重启)',
238
241
  defaultSelected: all.douyin.push.log
@@ -252,32 +255,32 @@ export default {
252
255
  className: 'ml-4 mr-4',
253
256
  subtitle: '此处为B站相关的用户偏好设置',
254
257
  children: [
255
- components.switch.create('cfg.bilibili.switch', {
258
+ components.switch.create('switch', {
256
259
  startText: '解析开关',
257
260
  description: 'B站解析开关,此开关为单独开关',
258
261
  defaultSelected: all.bilibili.switch
259
262
  }),
260
- components.switch.create('cfg.bilibili.tip', {
263
+ components.switch.create('tip', {
261
264
  startText: '解析提示',
262
265
  description: 'B站解析提示,发送提示信息:“检测到B站链接,开始解析”',
263
266
  defaultSelected: all.bilibili.tip
264
267
  }),
265
- components.switch.create('cfg.bilibili.comment', {
268
+ components.switch.create('comment', {
266
269
  startText: '评论解析',
267
270
  description: 'B站评论解析,开启后可发送B站作品评论图',
268
271
  defaultSelected: all.bilibili.comment
269
272
  }),
270
- components.input.number('cfg.bilibili.numcomment', {
273
+ components.input.number('numcomment', {
271
274
  label: '评论解析数量',
272
275
  defaultValue: all.bilibili.numcomment.toString(),
273
276
  rules: [{ min: 1 }]
274
277
  }),
275
- components.switch.create('cfg.bilibili.videopriority', {
278
+ components.switch.create('videopriority', {
276
279
  startText: '优先保内容',
277
280
  description: '解析视频是否优先保内容,true为优先保证上传将使用最低分辨率,false为优先保清晰度将使用最高分辨率',
278
281
  defaultSelected: all.bilibili.videopriority
279
282
  }),
280
- components.switch.create('cfg.bilibili.autoResolution', {
283
+ components.switch.create('autoResolution', {
281
284
  startText: '自动分辨率',
282
285
  description: '根据「视频拦截阈值」自动选择合适的分辨率,关闭后默认选择最大分辨率进行下载',
283
286
  defaultSelected: all.bilibili.autoResolution
@@ -286,70 +289,70 @@ export default {
286
289
  description: 'B站推送相关',
287
290
  descPosition: 20
288
291
  }),
289
- components.switch.create('cfg.bilibili.push.switch', {
292
+ components.switch.create('push.switch', {
290
293
  startText: '推送开关',
291
294
  description: '推送开关,开启后需重启;使用「#设置B站推送 + UID」配置推送列表',
292
295
  defaultSelected: all.bilibili.push.switch
293
296
  }),
294
- components.input.group('cfg.bilibili.push.banWords', {
297
+ components.input.group('push.banWords', {
295
298
  label: '动态中有以下指定关键词时,不推送',
296
299
  maxRows: 2,
297
300
  itemsPerRow: 4,
298
301
  data: all.bilibili.push.banWords,
299
- template: components.input.string('cfg.bilibili.push.banWords', {
302
+ template: components.input.string('push.banWords', {
300
303
  placeholder: '',
301
304
  label: '',
302
305
  color: 'success'
303
306
  })
304
307
  }),
305
- components.input.group('cfg.bilibili.push.banTags', {
308
+ components.input.group('push.banTags', {
306
309
  label: '动态中有指定标签时,不推送',
307
310
  maxRows: 2,
308
311
  itemsPerRow: 4,
309
312
  data: all.bilibili.push.banWords,
310
- template: components.input.string('cfg.bilibili.push.banTags', {
313
+ template: components.input.string('push.banTags', {
311
314
  placeholder: '',
312
315
  label: '',
313
316
  color: 'success'
314
317
  })
315
318
  }),
316
- components.radio.group('cfg.bilibili.push.permission', {
319
+ components.radio.group('push.permission', {
317
320
  label: '谁可以设置推送',
318
321
  orientation: 'horizontal',
319
322
  defaultValue: all.bilibili.push.permission,
320
323
  radio: [
321
- components.radio.create('cfg.bilibili.push.permission.radio-1', {
324
+ components.radio.create('push.permission.radio-1', {
322
325
  label: '所有人',
323
326
  value: 'all'
324
327
  }),
325
- components.radio.create('cfg.bilibili.push.permission.radio-2', {
328
+ components.radio.create('push.permission.radio-2', {
326
329
  label: '管理员',
327
330
  value: 'admin'
328
331
  }),
329
- components.radio.create('cfg.bilibili.push.permission.radio-3', {
332
+ components.radio.create('push.permission.radio-3', {
330
333
  label: '主人',
331
334
  value: 'master'
332
335
  }),
333
- components.radio.create('cfg.bilibili.push.permission.radio-4', {
336
+ components.radio.create('push.permission.radio-4', {
334
337
  label: '群主',
335
338
  value: 'group.owner'
336
339
  }),
337
- components.radio.create('cfg.bilibili.push.permission.radio-5', {
340
+ components.radio.create('push.permission.radio-5', {
338
341
  label: '群管理员',
339
342
  value: 'group.admin'
340
343
  })
341
344
  ]
342
345
  }),
343
- components.input.string('cfg.bilibili.push.cron', {
346
+ components.input.string('push.cron', {
344
347
  label: '定时任务表达式',
345
348
  defaultValue: all.bilibili.push.cron
346
349
  }),
347
- components.switch.create('cfg.bilibili.push.parsedynamic', {
350
+ components.switch.create('push.parsedynamic', {
348
351
  startText: '作品解析',
349
352
  description: '触发推送时是否一同解析该作品',
350
353
  defaultSelected: all.bilibili.push.parsedynamic
351
354
  }),
352
- components.switch.create('cfg.bilibili.push.log', {
355
+ components.switch.create('push.log', {
353
356
  startText: '推送日志',
354
357
  description: '是否打印推送日志(修改后需重启)',
355
358
  defaultSelected: all.bilibili.push.log
@@ -369,22 +372,22 @@ export default {
369
372
  className: 'ml-4 mr-4',
370
373
  subtitle: '此处为快手相关的用户偏好设置',
371
374
  children: [
372
- components.switch.create('cfg.kuaishou.switch', {
375
+ components.switch.create('switch', {
373
376
  startText: '解析开关',
374
377
  description: '快手解析开关,此开关为单独开关',
375
378
  defaultSelected: all.kuaishou.switch
376
379
  }),
377
- components.switch.create('cfg.kuaishou.tip', {
380
+ components.switch.create('tip', {
378
381
  startText: '解析提示',
379
382
  description: '抖音解析提示,发送提示信息:“检测到快手链接,开始解析”',
380
383
  defaultSelected: all.kuaishou.tip
381
384
  }),
382
- components.switch.create('cfg.kuaishou.comment', {
385
+ components.switch.create('comment', {
383
386
  startText: '评论解析',
384
387
  description: '快手评论解析,开启后可发送抖音作品评论图',
385
388
  defaultSelected: all.kuaishou.comment
386
389
  }),
387
- components.input.number('cfg.kuaishou.numcomment', {
390
+ components.input.number('numcomment', {
388
391
  label: '评论解析数量',
389
392
  defaultValue: all.kuaishou.numcomment.toString(),
390
393
  rules: [{ min: 1 }]
@@ -404,48 +407,48 @@ export default {
404
407
  className: 'ml-4 mr-4',
405
408
  subtitle: '此处为上传相关的用户偏好设置',
406
409
  children: [
407
- components.switch.create('cfg.upload.sendbase64', {
410
+ components.switch.create('sendbase64', {
408
411
  startText: '转换Base64',
409
412
  description: '发送视频经本插件转换为base64格式后再发送,适合Karin与机器人不在同一网络环境下开启',
410
413
  defaultSelected: all.upload.swisendbase64tch
411
414
  }),
412
- components.switch.create('cfg.upload.usefilelimit', {
415
+ components.switch.create('usefilelimit', {
413
416
  startText: '视频上传拦截',
414
417
  description: '开启后会根据视频文件大小判断是否需要上传,需配置「视频拦截阈值」。',
415
418
  defaultSelected: all.upload.usefilelimit
416
419
  }),
417
- components.input.number('cfg.upload.filelimit', {
420
+ components.input.number('filelimit', {
418
421
  label: '视频拦截阈值',
419
422
  description: '视频文件大于该数值则直接结束任务,不会上传,单位: MB,「视频上传拦截」开启后才会生效。',
420
423
  defaultValue: all.upload.filelimit.toString(),
421
424
  rules: [{ min: 1 }],
422
425
  isDisabled: !all.upload.usefilelimit
423
426
  }),
424
- components.switch.create('cfg.upload.compress', {
427
+ components.switch.create('compress', {
425
428
  startText: '压缩视频',
426
429
  description: '开启后会将视频文件压缩后再上传,适合上传大文件,任务过程中会吃满CPU,对低配服务器不友好。需配置「压缩触发阈值」与「压缩后的值」',
427
430
  defaultSelected: all.upload.compress
428
431
  }),
429
- components.input.number('cfg.upload.compresstrigger', {
432
+ components.input.number('compresstrigger', {
430
433
  label: '压缩触发阈值',
431
434
  description: '触发视频压缩的阈值,单位:MB。当文件大小超过该值时,才会压缩视频,「压缩视频」开启后才会生效',
432
435
  defaultValue: all.upload.compresstrigger.toString(),
433
436
  rules: [{ min: 1 }],
434
437
  isDisabled: !all.upload.compress
435
438
  }),
436
- components.input.number('cfg.upload.compressvalue', {
439
+ components.input.number('compressvalue', {
437
440
  label: '压缩后的值',
438
441
  description: '单位:MB,若视频文件大小大于「压缩触发阈值」的值,则会进行压缩至该值(±5%),「压缩视频」开启后才会生效',
439
442
  defaultValue: all.upload.compressvalue.toString(),
440
443
  rules: [{ min: 1 }],
441
444
  isDisabled: !all.upload.compress
442
445
  }),
443
- components.switch.create('cfg.upload.usegroupfile', {
446
+ components.switch.create('usegroupfile', {
444
447
  startText: '群文件上传',
445
448
  description: '使用群文件上传,开启后会将视频文件上传到群文件中,需配置「群文件上传阈值」',
446
449
  defaultSelected: all.upload.usegroupfile
447
450
  }),
448
- components.input.number('cfg.upload.groupfilevalue', {
451
+ components.input.number('groupfilevalue', {
449
452
  label: '群文件上传阈值',
450
453
  description: '当文件大小超过该值时将使用群文件上传,单位:MB,「使用群文件上传」开启后才会生效',
451
454
  defaultValue: all.upload.groupfilevalue.toString(),
@@ -544,7 +547,7 @@ export default {
544
547
  ],
545
548
  /** 前端点击保存之后调用的方法 */
546
549
  save: (config) => {
547
- const formatCfg = processFrontendConfig(config);
550
+ const formatCfg = processFrontendData(config);
548
551
  const oldAllCfg = Config.All();
549
552
  /** 合并旧新配置 */
550
553
  const fullData = _.mergeWith({}, oldAllCfg, formatCfg, customizer);
@@ -557,6 +560,8 @@ export default {
557
560
  }
558
561
  });
559
562
  return {
563
+ fullData,
564
+ formatCfg,
560
565
  success,
561
566
  message: success ? '保存成功 Ciallo~(∠・ω< )⌒☆' : '配置无变化,无需保存'
562
567
  };
@@ -647,137 +652,56 @@ const deepEqual = (a, b) => {
647
652
  };
648
653
  /**
649
654
  * str 转 num
650
- * @param value 字符串或者数字
655
+ * @param value 字符串
651
656
  * @returns
652
657
  */
653
- const convertToNumber = (value) => {
654
- if (typeof value === 'string') {
655
- return parseInt(value, 10);
656
- }
657
- return value;
658
- };
658
+ function convertToNumber(value) {
659
+ const num = parseInt(value);
660
+ return isNaN(num) ? value : num;
661
+ }
659
662
  /**
660
- * 转换前端传回来的配置成定义的配置文件格式
661
- * @param frontendConfig 前端传回来的原始内容
662
- * @returns
663
+ * 获取数组中的第一个对象,如果数组为空则返回空对象
664
+ * @param arr 数组
665
+ * @returns 数组中的第一个对象或空对象
663
666
  */
664
- const processFrontendConfig = (frontendConfig) => {
665
- const processedConfig = {
666
- app: {},
667
- bilibili: {},
668
- douyin: {},
669
- cookies: {},
670
- pushlist: {},
671
- upload: {},
672
- kuaishou: {}
673
- };
674
- // 处理cookies配置
675
- if (frontendConfig['cfg.cookies'] && frontendConfig['cfg.cookies'].length > 0) {
676
- const cookiesData = frontendConfig['cfg.cookies'][0];
677
- processedConfig.cookies = {
678
- bilibili: cookiesData['cfg.cookies.bilibili'],
679
- douyin: cookiesData['cfg.cookies.douyin'],
680
- kuaishou: cookiesData['cfg.cookies.kuaishou']
681
- };
682
- }
683
- // 处理app配置
684
- if (frontendConfig['cfg.app'] && frontendConfig['cfg.app'].length > 0) {
685
- const appData = frontendConfig['cfg.app'][0];
686
- processedConfig.app = {
687
- defaulttool: appData['cfg.app.defaulttool'],
688
- priority: convertToNumber(appData['cfg.app.priority']),
689
- rmmp4: appData['cfg.app.rmmp4'],
690
- renderScale: convertToNumber(appData['cfg.app.renderScale']),
691
- APIServer: appData['cfg.app.APIServer'],
692
- APIServerPort: convertToNumber(appData['cfg.app.APIServerPort']),
693
- APIServerMount: appData['cfg.app.APIServerMount'],
694
- Theme: convertToNumber(appData['cfg.app.Theme'])
695
- };
696
- }
697
- // 处理douyin配置
698
- if (frontendConfig['cfg.douyin'] && frontendConfig['cfg.douyin'].length > 0) {
699
- const douyinData = frontendConfig['cfg.douyin'][0];
700
- processedConfig.douyin = {
701
- switch: douyinData['cfg.douyin.switch'],
702
- tip: douyinData['cfg.douyin.tip'],
703
- comment: douyinData['cfg.douyin.comment'],
704
- numcomment: convertToNumber(douyinData['cfg.douyin.numcomment']),
705
- autoResolution: douyinData['cfg.douyin.autoResolution'],
706
- push: {
707
- switch: douyinData['cfg.douyin.push.switch'],
708
- banWords: douyinData['cfg.douyin.push.banWords'],
709
- banTags: douyinData['cfg.douyin.push.banTags'],
710
- permission: douyinData['cfg.douyin.push.permission'],
711
- cron: douyinData['cfg.douyin.push.cron'],
712
- parsedynamic: douyinData['cfg.douyin.push.parsedynamic'],
713
- log: douyinData['cfg.douyin.push.log']
667
+ function getFirstObject(arr) {
668
+ return arr.length > 0 ? arr[0] : {};
669
+ }
670
+ /**
671
+ * 处理前端返回的数据,将其转换为 ConfigType 格式
672
+ * @param data 前端返回的数据
673
+ * @returns 处理后符合 ConfigType 格式的数据
674
+ */
675
+ function processFrontendData(data) {
676
+ const result = {};
677
+ // 处理普通配置项
678
+ // const configKeys = ['app', 'bilibili', 'douyin', 'cookies', 'kuaishou', 'upload']
679
+ const configKeys = Object.keys(data).filter(key => !key.includes('pushlist'));
680
+ for (const key of configKeys) {
681
+ const firstObj = getFirstObject(data[key] || []);
682
+ result[key] = {};
683
+ for (const prop in firstObj) {
684
+ let value = firstObj[prop];
685
+ // 尝试将值转换为数字
686
+ value = convertToNumber(value);
687
+ if (prop.includes('.')) {
688
+ // 处理嵌套属性
689
+ const [parent, child] = prop.split('.');
690
+ if (!result[key][parent]) {
691
+ result[key][parent] = {};
692
+ }
693
+ result[key][parent][child] = value;
714
694
  }
715
- };
716
- }
717
- // 处理bilibili配置
718
- if (frontendConfig['cfg.bilibili'] && frontendConfig['cfg.bilibili'].length > 0) {
719
- const bilibiliData = frontendConfig['cfg.bilibili'][0];
720
- processedConfig.bilibili = {
721
- switch: bilibiliData['cfg.bilibili.switch'],
722
- tip: bilibiliData['cfg.bilibili.tip'],
723
- comment: bilibiliData['cfg.bilibili.comment'],
724
- numcomment: convertToNumber(bilibiliData['cfg.bilibili.numcomment']),
725
- videopriority: bilibiliData['cfg.bilibili.videopriority'],
726
- autoResolution: bilibiliData['cfg.bilibili.autoResolution'],
727
- push: {
728
- switch: bilibiliData['cfg.bilibili.push.switch'],
729
- banWords: bilibiliData['cfg.bilibili.push.banWords'],
730
- banTags: bilibiliData['cfg.bilibili.push.banTags'],
731
- permission: bilibiliData['cfg.bilibili.push.permission'],
732
- cron: bilibiliData['cfg.bilibili.push.cron'],
733
- parsedynamic: bilibiliData['cfg.bilibili.push.parsedynamic'],
734
- log: bilibiliData['cfg.bilibili.push.log']
695
+ else {
696
+ // 处理普通属性
697
+ result[key][prop] = value;
735
698
  }
736
- };
737
- }
738
- // 处理kuaishou配置
739
- if (frontendConfig['cfg.kuaishou'] && frontendConfig['cfg.kuaishou'].length > 0) {
740
- const kuaishouData = frontendConfig['cfg.kuaishou'][0];
741
- processedConfig.kuaishou = {
742
- switch: kuaishouData['cfg.kuaishou.switch'],
743
- tip: kuaishouData['cfg.kuaishou.tip'],
744
- comment: kuaishouData['cfg.kuaishou.comment'],
745
- numcomment: convertToNumber(kuaishouData['cfg.kuaishou.numcomment'])
746
- };
747
- }
748
- // 处理upload配置
749
- if (frontendConfig['cfg.upload'] && frontendConfig['cfg.upload'].length > 0) {
750
- const uploadData = frontendConfig['cfg.upload'][0];
751
- processedConfig.upload = {
752
- sendbase64: uploadData['cfg.upload.sendbase64'],
753
- usefilelimit: uploadData['cfg.upload.usefilelimit'],
754
- filelimit: convertToNumber(uploadData['cfg.upload.filelimit']),
755
- compress: uploadData['cfg.upload.compress'],
756
- compresstrigger: convertToNumber(uploadData['cfg.upload.compresstrigger']),
757
- compressvalue: convertToNumber(uploadData['cfg.upload.compressvalue']),
758
- usegroupfile: uploadData['cfg.upload.usegroupfile'],
759
- groupfilevalue: convertToNumber(uploadData['cfg.upload.groupfilevalue'])
760
- };
699
+ }
761
700
  }
762
- // 处理pushlist配置
763
- processedConfig.pushlist = {
764
- douyin: [],
765
- bilibili: []
701
+ // 处理 pushlist 配置项
702
+ result.pushlist = {
703
+ douyin: data['cfg.pushlist.douyin'] || [],
704
+ bilibili: data['cfg.pushlist.bilibili'] || []
766
705
  };
767
- if (frontendConfig['cfg.pushlist.douyin'] && frontendConfig['cfg.pushlist.douyin'].length > 0) {
768
- processedConfig.pushlist.douyin = frontendConfig['cfg.pushlist.douyin'].map((item) => ({
769
- sec_uid: item.sec_uid,
770
- short_id: item.short_id,
771
- group_id: item.group_id,
772
- remark: item.remark
773
- }));
774
- }
775
- if (frontendConfig['cfg.pushlist.bilibili'] && frontendConfig['cfg.pushlist.bilibili'].length > 0) {
776
- processedConfig.pushlist.bilibili = frontendConfig['cfg.pushlist.bilibili'].map((item) => ({
777
- host_mid: convertToNumber(item.host_mid),
778
- group_id: item.group_id,
779
- remark: item.remark
780
- }));
781
- }
782
- return processedConfig;
783
- };
706
+ return result;
707
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "karin-plugin-kkk",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "a Karin video parsing tool",
5
5
  "keywords": [
6
6
  "karin-plugin",
@@ -32,17 +32,16 @@
32
32
  "build": "tsc --project tsconfig.json && tsc-alias -p tsconfig.json",
33
33
  "clean": "npm lib/cli/pr.js clean",
34
34
  "commit": "node lib/cli/commit.js",
35
- "dev": "tsx watch src/index.ts",
35
+ "dev": "tsx src/index.ts",
36
+ "watch": "tsx watch --include \"src/**/*.ts\" src/index.ts",
36
37
  "fix": "eslint src/**/*.ts --fix",
37
- "init": "karin init",
38
38
  "pr": "node lib/cli/pr.js",
39
39
  "pub": "npm publish --access public",
40
40
  "pub-beta": "npm publish --tag beta",
41
- "sort": "npx sort-package-json",
42
- "start": "karin start"
41
+ "sort": "npx sort-package-json"
43
42
  },
44
43
  "dependencies": {
45
- "@ikenxuan/amagi": "^4.4.7",
44
+ "@ikenxuan/amagi": "^4.4.8",
46
45
  "@karinjs/md-html": "^1.1.6",
47
46
  "cors": "^2.8.5",
48
47
  "heic-convert": "^2.1.0",