Skip to content

Commit

Permalink
Merge pull request #782 from terwer/feature/hotfix
Browse files Browse the repository at this point in the history
feat: #773 偏好设置数据持久化
  • Loading branch information
terwer authored Oct 11, 2023
2 parents 8d73688 + 1b2608d commit fa751e0
Show file tree
Hide file tree
Showing 15 changed files with 265 additions and 55 deletions.
4 changes: 2 additions & 2 deletions esbuild.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ const isWindows = os.platform() === "win32"

let baseDir
if (isWatch || isServe) {
// baseDir = "/Users/terwer/Documents/mydocs/SiYuanWorkspace/test/data/plugins/siyuan-plugin-publisher"
baseDir = "/Users/zhangyue/Documents/terwer/SiyuanWorkspace/test/data/plugins/siyuan-plugin-publisher"
baseDir = "/Users/terwer/Documents/mydocs/SiYuanWorkspace/test/data/plugins/siyuan-plugin-publisher"
// baseDir = "/Users/zhangyue/Documents/terwer/SiyuanWorkspace/test/data/plugins/siyuan-plugin-publisher"
// baseDir = "/Users/terwer/Documents/mydocs/SiYuanWorkspace/public/data/plugins/siyuan-plugin-publisher"
if (isWindows) {
baseDir = "C:\\Users\\terwer\\Documents\\mydocs\\SiyuanWorkspace\\test\\data\\plugins\\siyuan-plugin-publisher"
Expand Down
12 changes: 5 additions & 7 deletions src/components/publish/form/CommonCategories.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,11 @@
<script setup lang="ts">
import { createAppLogger } from "~/src/utils/appLogger.ts"
import { useVueI18n } from "~/src/composables/useVueI18n.ts"
import { nextTick, reactive, ref } from "vue"
import { watch } from "vue"
import { nextTick, reactive, ref, watch } from "vue"
import { CategoryAIResult, prompt } from "~/src/utils/ai/prompt.ts"
import { useChatGPT } from "~/src/composables/useChatGPT.ts"
import { HtmlUtil, JsonUtil, StrUtil } from "zhi-common"
import { JsonUtil, StrUtil } from "zhi-common"
import { ElMessage } from "element-plus"
import { AiConstants } from "~/src/utils/ai/AiConstants.ts"

const logger = createAppLogger("common-categories")
const { t } = useVueI18n()
Expand Down Expand Up @@ -113,10 +111,10 @@ const cateMethods = {
formData.isLoading = true

const inputWord = prompt.categoryPrompt.content
const { chat } = useChatGPT()
const { chat, getChatInput } = useChatGPT()
const chatText = await chat(inputWord, {
name: "categories",
systemMessage: formData.md?.substring(0, AiConstants.MAX_INPUT_TOKEN_LENGTH) ?? HtmlUtil.parseHtml(formData.html, AiConstants.MAX_INPUT_TOKEN_LENGTH, true),
systemMessage: getChatInput(formData?.md, formData.html),
})
if (StrUtil.isEmptyString(chatText)) {
ElMessage.error("请求错误,请在偏好设置配置请求地址和ChatGPT key!")
Expand Down Expand Up @@ -213,4 +211,4 @@ const cateMethods = {

.recomm-cate
margin 0 10px
</style>
</style>
24 changes: 11 additions & 13 deletions src/components/publish/form/PublishCategories.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,14 @@

<script setup lang="ts">
import { CategoryTypeEnum } from "zhi-blog-api"
import { reactive, toRaw } from "vue"
import { reactive, toRaw, watch } from "vue"
import { ICategoryConfig, IMultiCategoriesConfig } from "~/src/types/ICategoryConfig.ts"
import { createAppLogger } from "~/src/utils/appLogger.ts"
import { useVueI18n } from "~/src/composables/useVueI18n.ts"
import { watch } from "vue"
import { CategoryAIResult, prompt, TagAIResult } from "~/src/utils/ai/prompt.ts"
import { CategoryAIResult, prompt } from "~/src/utils/ai/prompt.ts"
import { useChatGPT } from "~/src/composables/useChatGPT.ts"
import {HtmlUtil, JsonUtil, StrUtil} from "zhi-common"
import { JsonUtil, StrUtil } from "zhi-common"
import { ElMessage } from "element-plus"
import {AiConstants} from "~/src/utils/ai/AiConstants.ts";

const logger = createAppLogger("publish-categories")
const { t } = useVueI18n()
Expand Down Expand Up @@ -85,10 +83,10 @@ watch(
)

watch(
() => props.html,
(newValue) => {
formData.html = newValue
}
() => props.html,
(newValue) => {
formData.html = newValue
}
)

// emits
Expand All @@ -108,10 +106,10 @@ const fetchCate = async () => {
formData.isLoading = true

const inputWord = prompt.categoryPrompt.content
const { chat } = useChatGPT()
const chatText = await chat(inputWord,{
const { chat, getChatInput } = useChatGPT()
const chatText = await chat(inputWord, {
name: "categories",
systemMessage: formData.md?.substring(0, AiConstants.MAX_INPUT_TOKEN_LENGTH) ?? HtmlUtil.parseHtml(formData.html, AiConstants.MAX_INPUT_TOKEN_LENGTH, true),
systemMessage: getChatInput(formData?.md, formData.html),
})
if (StrUtil.isEmptyString(chatText)) {
ElMessage.error("请求错误,请在偏好设置配置请求地址和ChatGPT key!")
Expand Down Expand Up @@ -182,4 +180,4 @@ const fetchCate = async () => {

.recomm-cate
margin 0 10px
</style>
</style>
7 changes: 3 additions & 4 deletions src/components/publish/form/PublishDescription.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ import { useVueI18n } from "~/src/composables/useVueI18n.ts"
import { reactive, watch } from "vue"
import { createAppLogger } from "~/src/utils/appLogger.ts"
import { ElMessage } from "element-plus"
import { HtmlUtil, JsonUtil, SmartUtil, StrUtil } from "zhi-common"
import { JsonUtil, StrUtil } from "zhi-common"
import { prompt, ShortDescAIResult } from "~/src/utils/ai/prompt.ts"
import { useChatGPT } from "~/src/composables/useChatGPT.ts"
import { AiConstants } from "~/src/utils/ai/AiConstants.ts"

const logger = createAppLogger("publish-description")
const { t } = useVueI18n()
Expand Down Expand Up @@ -98,10 +97,10 @@ const handleMakeDesc = async () => {
try {
// if (formData.useAi) {
const inputWord = prompt.shortDescPrompt.content
const { chat } = useChatGPT()
const { chat, getChatInput } = useChatGPT()
const chatText = await chat(inputWord, {
name: "desc",
systemMessage: formData.md?.substring(0, AiConstants.MAX_INPUT_TOKEN_LENGTH) ?? HtmlUtil.parseHtml(formData.html, AiConstants.MAX_INPUT_TOKEN_LENGTH, true),
systemMessage: getChatInput(formData?.md, formData.html),
})
if (StrUtil.isEmptyString(chatText)) {
ElMessage.error("请求错误,请在偏好设置配置请求地址和ChatGPT key!")
Expand Down
7 changes: 3 additions & 4 deletions src/components/publish/form/PublishTags.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ import { useVueI18n } from "~/src/composables/useVueI18n.ts"
import { nextTick, reactive, ref, watch } from "vue"
import { ElMessage } from "element-plus"
import { createAppLogger } from "~/src/utils/appLogger.ts"
import { HtmlUtil, JsonUtil, StrUtil } from "zhi-common"
import { JsonUtil, StrUtil } from "zhi-common"
import { prompt, TagAIResult } from "~/src/utils/ai/prompt.ts"
import { useChatGPT } from "~/src/composables/useChatGPT.ts"
import { AiConstants } from "~/src/utils/ai/AiConstants.ts"

const logger = createAppLogger("publish-tags")
const { t } = useVueI18n()
Expand Down Expand Up @@ -116,10 +115,10 @@ const tagMethods = {
formData.isTagLoading = true

const inputWord = prompt.tagPrompt.content
const { chat } = useChatGPT()
const { chat, getChatInput } = useChatGPT()
const chatText = await chat(inputWord, {
name: "tags",
systemMessage: formData.md?.substring(0, AiConstants.MAX_INPUT_TOKEN_LENGTH) ?? (formData.html, AiConstants.MAX_INPUT_TOKEN_LENGTH, true),
systemMessage: getChatInput(formData?.md, formData.html),
})
if (StrUtil.isEmptyString(chatText)) {
ElMessage.error("请求错误,请在偏好设置配置请求地址和ChatGPT key!")
Expand Down
20 changes: 10 additions & 10 deletions src/components/publish/form/PublishTitle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@
<script setup lang="ts">
import { reactive, watch } from "vue"
import { useVueI18n } from "~/src/composables/useVueI18n.ts"
import { HtmlUtil, JsonUtil, StrUtil } from "zhi-common"
import { JsonUtil, StrUtil } from "zhi-common"
import { ElMessage } from "element-plus"
import { useChatGPT } from "~/src/composables/useChatGPT.ts"
import { createAppLogger } from "~/src/utils/appLogger.ts"
import { prompt, TitleAIResult } from "~/src/utils/ai/prompt.ts"
import { AiConstants } from "~/src/utils/ai/AiConstants.ts"

const logger = createAppLogger("publish-title")
const { t } = useVueI18n()
Expand Down Expand Up @@ -77,12 +76,12 @@ watch(
}
)

// watch(
// () => props.md,
// (newValue) => {
// formData.md = newValue
// }
// )
watch(
() => props.md,
(newValue) => {
formData.md = newValue
}
)

watch(
() => props.html,
Expand All @@ -101,10 +100,11 @@ const handleMakeTitle = async () => {
try {
formData.isLoading = true
const inputWord = prompt.titlePrompt.content
const { chat } = useChatGPT()
const { chat, getChatInput } = useChatGPT()

const chatText = await chat(inputWord, {
name: "title",
systemMessage: formData.md?.substring(0, AiConstants.MAX_INPUT_TOKEN_LENGTH) ?? HtmlUtil.parseHtml(formData.html, AiConstants.MAX_INPUT_TOKEN_LENGTH, true),
systemMessage: getChatInput(formData?.md, formData.html),
})
if (StrUtil.isEmptyString(chatText)) {
ElMessage.error("请求错误,请在偏好设置配置请求地址和ChatGPT key!")
Expand Down
16 changes: 15 additions & 1 deletion src/composables/useChatGPT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
*/

import { usePublishPreferenceSetting } from "~/src/stores/usePublishPreferenceSetting.ts"
import { StrUtil } from "zhi-common"
import { HtmlUtil, StrUtil } from "zhi-common"
import { ChatGPTAPI, ChatGPTUnofficialProxyAPI, SendMessageOptions } from "chatgpt"
import { Utils } from "~/src/utils/utils.ts"
import { isDev } from "~/src/utils/constants.ts"
import { createAppLogger } from "~/src/utils/appLogger.ts"
import { AiConstants } from "~/src/utils/ai/AiConstants.ts"

/**
* 创建一个用于与 ChatGPT 服务进行交互的钩子
Expand Down Expand Up @@ -96,7 +97,20 @@ const useChatGPT = () => {
}
}

/**
* 获取聊天输入
*
* @param input1 可能为空的输入1,优先级高
* @param input2 不为空的输入2,优先级低
*/
const getChatInput = (input1: string, input2: string) => {
const md = input1.substring(0, AiConstants.MAX_INPUT_TOKEN_LENGTH)
const html = HtmlUtil.parseHtml(input2, AiConstants.MAX_INPUT_TOKEN_LENGTH, true)
return Utils.emptyOrDefault(md, html)
}

return {
getChatInput,
chat,
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/locales/zh_CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ export default {
"main.auto.fetch.title": "自动提取标题",
"main.auto.fetch.cate": "自动提取分类",
"category.ai.hand": "由于各平台分类体系不一致,分类需要手动进行校准,不会自动保存",
"category.ai.enabled": "检测到您已经配置AI,可请前往详细模式进行操作",
"category.ai.enabled": "检测到您已经配置AI,可请前往详细模式进行操作。小贴士:由于网络或者其他问题,如果第一次失败生成,多试几次或许就能出结果哟~😄",
"sys.config.ai": "AI设置",
"config.ai.use.siyuan": "思源笔记内部,直接使用思源笔记配置,无需配置",
"setting.blog.yamlLinkEnabled": "YAML永久链接",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { SiyuanDevice } from "zhi-device"
* @version 0.9.0
* @since 0.9.0
*/
class CommonStorage implements StorageLikeAsync {
class CommonStorageAsync implements StorageLikeAsync {
private readonly logger
private readonly storageViaSiyuanApi
private readonly kernelApi
Expand Down Expand Up @@ -112,7 +112,7 @@ class CommonStorage implements StorageLikeAsync {
* @returns 一个 Promise,在设置值后解析。
*/
public async setItem(key: string, value: string): Promise<void> {
// this.logger.debug(`Setting value for '${key}' in CommonStorage to '${value}'.`)
// this.logger.debug(`Setting value for '${key}' in CommonStorageAsync to '${value}'.`)
if (this.storageViaSiyuanApi) {
// 如果当前运行在思源笔记中,则直接返回空字符串
await this.kernelApi.saveTextData(key, value)
Expand All @@ -125,4 +125,4 @@ class CommonStorage implements StorageLikeAsync {
}
}

export default CommonStorage
export default CommonStorageAsync
125 changes: 125 additions & 0 deletions src/stores/common/jsonStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright (c) 2023, Terwer . All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Terwer designates this
* particular file as subject to the "Classpath" exception as provided
* by Terwer in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Terwer, Shenzhen, Guangdong, China, [email protected]
* or visit www.terwer.space if you need additional information or have any
* questions.
*/

import { StorageLike } from "@vueuse/core"
import { createAppLogger } from "~/src/utils/appLogger.ts"
import { SiyuanDevice } from "zhi-device"
import { JsonUtil } from "zhi-common"

/**
* JSON 同步存储实现,实现了 `StorageLikeAsync` 接口。
* https://github.com/vueuse/vueuse/blob/main/packages/core/ssr-handlers.ts#L11
*
* @author terwer
* @version 1.7.0
* @since 1.7.0
*/
class JsonStorage implements StorageLike {
private readonly logger: any
private readonly fs: any
private readonly path: any
private readonly filePath: string

constructor(filePath: string) {
this.logger = createAppLogger("json-storage")

// 动态导入依赖
const win = SiyuanDevice.siyuanWindow()
this.fs = win.require("fs")
this.path = win.require("path")

// 确保文件存在
const basePath = win?.siyuan.config.system.dataDir
this.filePath = this.path.join(basePath, filePath)
const storeDir = this.path.dirname(this.filePath)
this.logger.info("store dir =>", storeDir)
// 确保有目录
if (!this.fs.existsSync(storeDir)) {
this.fs.mkdirSync(storeDir)
}
// 确保文件已经初始化
if (!this.fs.existsSync(this.filePath)) {
this.writeFile({})
}
this.logger.info("ininted json local storage in =>", this.filePath)
}

/**
* 获取存储中的项目
*
* @param {string} key - 存储项的键名
* @returns {string | null} - 如果找到存储项,将返回其值;否则返回 null
*/
public getItem(key: string): string | null {
// this.logger.info("get item from json")
return this.getStoredItems()[key] || null
}

/**
* 设置存储项的值
*
* @param {string} key - 存储项的键名
* @param {string} value - 要存储的值
*/
public setItem(key: string, value: string): void {
// this.logger.info("set item from json")
const obj = this.getStoredItems()
obj[key] = value
this.writeFile(obj)
}

/**
* 从存储中移除指定的项
*
* @param {string} key - 要移除的存储项的键名
*/
public removeItem(key: string): void {
// this.logger.info("removeItem item from json")
const obj = this.getStoredItems()
delete obj[key]
this.writeFile(obj)
}

// ================
// private methods
// ================
private getStoredItems() {
return JsonUtil.safeParse<any>(this.readFile(), {})
}

private readFile() {
return this.fs.readFileSync(this.filePath, this.getFileOptions())
}

private writeFile(obj) {
return this.fs.writeFileSync(this.filePath, JSON.stringify(obj), this.getFileOptions())
}

private getFileOptions() {
return { encoding: "utf8" } as any
}
}

export default JsonStorage
Loading

0 comments on commit fa751e0

Please sign in to comment.