hexo-theme-shokax 0.4.21 → 0.4.22

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/_config.yml CHANGED
@@ -203,12 +203,12 @@ waline:
203
203
  lang: "zh-CN"
204
204
  locale: {} # https://waline.js.org/guide/features/i18n.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%AF%AD%E8%A8%80
205
205
  emoji: # 表情包
206
- - https://unpkg.com/@waline/emojis@1.0.1/weibo
207
- - https://unpkg.com/@waline/emojis@1.0.1/alus
208
- - https://unpkg.com/@waline/emojis@1.0.1/bilibili
209
- - https://unpkg.com/@waline/emojis@1.0.1/qq
210
- - https://unpkg.com/@waline/emojis@1.0.1/tieba
211
- - https://unpkg.com/@waline/emojis@1.0.1/tw-emoji
206
+ # - https://unpkg.com/@waline/emojis@1.0.1/weibo
207
+ # - https://unpkg.com/@waline/emojis@1.0.1/alus
208
+ # - https://unpkg.com/@waline/emojis@1.0.1/bilibili
209
+ # - https://unpkg.com/@waline/emojis@1.0.1/qq
210
+ # - https://unpkg.com/@waline/emojis@1.0.1/tieba
211
+ # - https://unpkg.com/@waline/emojis@1.0.1/tw-emoji
212
212
  meta: # 可以填写的内容
213
213
  - nick
214
214
  - mail
@@ -222,12 +222,12 @@ waline:
222
222
 
223
223
  summary:
224
224
  enable: false
225
- introduce: "我是基于ChatGPT-turbo-3.5实现的AI助手,在此网站上负责整理和概括文章" # AI自我介绍
226
- mode: openai # openai/custom
227
- pricing: "trial" # trial为试用模板(3 RPM);pay为即用即付模板(60 RPM)
228
- openai:
229
- remote: "https://api.openai.com"
230
- apikey: "key"
225
+ introduce: "" # AI自我介绍
226
+ model:
227
+ apiKey:
228
+ apiUrl:
229
+ temperature:
230
+ initalPrompt:
231
231
 
232
232
  # Social Links
233
233
  # Usage: `Key: permalink || icon || color`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-shokax",
3
- "version": "0.4.21",
3
+ "version": "0.4.22",
4
4
  "description": "a hexo theme based on shoka",
5
5
  "main": "index.js",
6
6
  "repository": "https://github.com/theme-shoka-x/hexo-theme-shokaX",
@@ -31,6 +31,7 @@
31
31
  "@waline/client": "^3.5.2",
32
32
  "algoliasearch": "5.20.3",
33
33
  "dompurify": "^3.2.4",
34
+ "es-toolkit": "^1.32.0",
34
35
  "esbuild": "^0.25.0",
35
36
  "hexo": "^7.3.0",
36
37
  "hexo-algoliasearch": "^2.0.1",
@@ -0,0 +1,115 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __copyProps = (to, from, except, desc) => {
8
+ if (from && typeof from === "object" || typeof from === "function") {
9
+ for (let key of __getOwnPropNames(from))
10
+ if (!__hasOwnProp.call(to, key) && key !== except)
11
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
+ }
13
+ return to;
14
+ };
15
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
16
+ // If the importer is in node compatibility mode or this is not an ESM
17
+ // file that has been converted to a CommonJS file using a Babel-
18
+ // compatible transform (i.e. "__esModule" has not been set), then set
19
+ // "default" to the CommonJS "module.exports" for node compatibility.
20
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
+ mod
22
+ ));
23
+ var import_node_crypto = require("node:crypto");
24
+ var import_promises = __toESM(require("node:fs/promises"));
25
+ async function getSummaryByAPI(content) {
26
+ const config = hexo.theme.config.summary;
27
+ const apiKey = config.apiKey;
28
+ const apiUrl = config.apiUrl;
29
+ const model = config.model;
30
+ const temperature = config.temperature ?? 1.3;
31
+ const initalPrompt = config.initalPrompt;
32
+ const res = await fetch(apiUrl, {
33
+ method: "POST",
34
+ headers: {
35
+ "Content-Type": "application/json",
36
+ "Authorization": `Bearer ${apiKey}`
37
+ },
38
+ body: JSON.stringify({
39
+ model,
40
+ messages: [{ role: "user", content: `${initalPrompt} ${content}` }],
41
+ temperature
42
+ })
43
+ });
44
+ if (!res.ok) {
45
+ throw new Error(`Error: ${res.status} ${res.statusText}`);
46
+ }
47
+ const data = await res.json();
48
+ if (data.error) {
49
+ throw new Error(`Error: ${data.error.message}`);
50
+ }
51
+ const summary = data.choices[0].message.content;
52
+ return summary;
53
+ }
54
+ class SummaryDatabase {
55
+ fileChanged;
56
+ data;
57
+ constructor() {
58
+ this.fileChanged = false;
59
+ this.data = {
60
+ version: 2,
61
+ features: {
62
+ incremental: false
63
+ },
64
+ summaries: {}
65
+ };
66
+ }
67
+ async readDB() {
68
+ try {
69
+ await import_promises.default.access("summary.json");
70
+ this.data = JSON.parse(await import_promises.default.readFile("summary.json", "utf-8"));
71
+ } catch (error) {
72
+ }
73
+ if (this.data.version !== 2) {
74
+ throw new Error(`Incompatible version of summary database: ${this.data.version}`);
75
+ }
76
+ }
77
+ async writeDB() {
78
+ if (this.fileChanged) {
79
+ await import_promises.default.writeFile("summary.json", JSON.stringify(this.data));
80
+ }
81
+ }
82
+ async getPostSummary(path, content) {
83
+ const pathHash = (0, import_node_crypto.createHash)("sha256").update(path).digest("hex");
84
+ const contentHash = (0, import_node_crypto.createHash)("sha256").update(content).digest("hex");
85
+ if (this.data.summaries[pathHash]?.sha256 === contentHash) {
86
+ return this.data.summaries[pathHash].summary;
87
+ } else {
88
+ const summaryContent = await getSummaryByAPI(content);
89
+ this.data.summaries[pathHash] = {
90
+ summary: summaryContent,
91
+ sha256: contentHash
92
+ };
93
+ this.fileChanged = true;
94
+ return summaryContent;
95
+ }
96
+ }
97
+ }
98
+ hexo.extend.generator.register("summary_ai", async function(locals) {
99
+ const posts = locals.posts;
100
+ if (!hexo.theme.config.summary.enable) {
101
+ return;
102
+ }
103
+ const db = new SummaryDatabase();
104
+ await db.readDB();
105
+ for (const post of posts.toArray()) {
106
+ const content = post.content;
107
+ const path = post.path;
108
+ const published = post.published;
109
+ if (content && path && published && content.length > 0) {
110
+ const summary = await db.getPostSummary(path, content);
111
+ post.summary = summary;
112
+ }
113
+ }
114
+ await db.writeDB();
115
+ });
@@ -1,112 +1,5 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __copyProps = (to, from, except, desc) => {
8
- if (from && typeof from === "object" || typeof from === "function") {
9
- for (let key of __getOwnPropNames(from))
10
- if (!__hasOwnProp.call(to, key) && key !== except)
11
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
- }
13
- return to;
14
- };
15
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
16
- // If the importer is in node compatibility mode or this is not an ESM
17
- // file that has been converted to a CommonJS file using a Babel-
18
- // compatible transform (i.e. "__esModule" has not been set), then set
19
- // "default" to the CommonJS "module.exports" for node compatibility.
20
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
- mod
22
- ));
23
- var import_node_fs = __toESM(require("node:fs"));
24
- function getContent(post) {
25
- return post?.raw ?? post?._content ?? post.content;
26
- }
27
- let db;
28
- function postMessage(path, content, dbPath, startMessage) {
29
- if (import_node_fs.default.existsSync("summary.json")) {
30
- db = JSON.parse(import_node_fs.default.readFileSync("summary.json", { encoding: "utf-8" }));
31
- } else {
32
- db = {};
33
- }
34
- const config = hexo.theme.config.summary;
35
- if (config.enable) {
36
- if (typeof db?.[path] !== "undefined" && typeof db?.[path]?.[dbPath] !== "undefined") {
37
- return db[path][dbPath];
38
- } else {
39
- if (typeof db?.[path] === "undefined") {
40
- db[path] = {};
41
- } else {
42
- db[path][dbPath] = "";
43
- }
44
- }
45
- if (config.mode === "openai") {
46
- const request = () => {
47
- fetch(`${config.openai.remote}/v1/chat/completions`, {
48
- method: "POST",
49
- headers: requestHeaders,
50
- body: JSON.stringify(requestBody)
51
- }).then((response) => {
52
- if (!response.ok) {
53
- throw Error("ERROR: Failed to get summary from Openai API");
54
- }
55
- response.json().then((data) => {
56
- const summary = data.choices[0].message.content;
57
- try {
58
- db[path][dbPath] = summary;
59
- } catch (e) {
60
- db ??= {};
61
- db[path] ??= {};
62
- db[path][dbPath] ??= "";
63
- db[path][dbPath] = summary;
64
- }
65
- import_node_fs.default.writeFileSync("summary.json", JSON.stringify(db));
66
- if (import_node_fs.default.existsSync("requested.lock")) {
67
- import_node_fs.default.unlinkSync("requested.lock");
68
- }
69
- return summary;
70
- });
71
- });
72
- };
73
- const checkTime = (waitTime) => {
74
- if (import_node_fs.default.existsSync("request.lock")) {
75
- if (import_node_fs.default.existsSync("requested.lock")) {
76
- setTimeout(checkTime, 1e3 * waitTime);
77
- return;
78
- }
79
- import_node_fs.default.writeFileSync("requested.lock", "");
80
- setTimeout(request, 1e3 * 2.5 * waitTime);
81
- import_node_fs.default.unlinkSync("request.lock");
82
- } else {
83
- import_node_fs.default.writeFileSync("request.lock", "");
84
- request();
85
- }
86
- };
87
- const requestHeaders = {
88
- "Content-Type": "application/json",
89
- Authorization: `Bearer ${config.openai.apikey}`
90
- };
91
- const requestBody = {
92
- model: "gpt-3.5-turbo",
93
- messages: [{ role: "user", content: `${startMessage} ${content}` }],
94
- temperature: 0.7
95
- };
96
- if (config.pricing === "trial") {
97
- hexo.log.info("Requesting OpenAI API... (3 RPM mode)");
98
- hexo.log.info("It may take 20 minutes or more (depending on the number of articles, each one takes 25 seconds)");
99
- checkTime(10);
100
- } else {
101
- hexo.log.info("Requesting OpenAI API... (60 RPM mode)");
102
- checkTime(0.5);
103
- }
104
- } else {
105
- }
106
- }
107
- }
108
1
  hexo.extend.helper.register("get_summary", (post) => {
109
- return postMessage(post.path, getContent(post), "summary", "\u8BF7\u4E3A\u4E0B\u8FF0\u6587\u7AE0\u63D0\u4F9B\u4E00\u4EFD200\u5B57\u4EE5\u5185\u7684\u6982\u62EC\uFF0C\u4F7F\u7528\u4E2D\u6587\u56DE\u7B54\u4E14\u5C3D\u53EF\u80FD\u7B80\u6D01: ");
2
+ return post.summary;
110
3
  });
111
4
  hexo.extend.helper.register("get_introduce", () => {
112
5
  return hexo.theme.config.summary.introduce;