Skip to content

Commit

Permalink
feat: AI集成
Browse files Browse the repository at this point in the history
  • Loading branch information
terwer committed Aug 23, 2023
1 parent ff837b0 commit c701ce6
Show file tree
Hide file tree
Showing 21 changed files with 447 additions and 106 deletions.
38 changes: 12 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,18 @@ Publish articles from siyuan-note to platforms such as Yuque, Notion, Cnblogs, W

Support features such as fast publishing, image bed management, platform expansion, smart labels, etc.

> **Front Announcement 1: The first version `1.9.0` for Publish Tools that supports release view and AI beta early adopter is released!**
>
> **Front Announcement 2: Version `1.8.0` released with full support for image upload in the Publish Tools!**
Tips: Zhihu uses the image upload of the Zhihu platform, Yuque, Notion, and Hexo need Picgo plugin support, and the Metaweblog series platform supports both Picgo plugin and self-contained image upload (install Picgo plugin to use Picgo plugin, otherwise use their own platform)

We recommend that you use the `uninstall->install` method to update. If the configuration is abnormal, please backup `[workspace]/data/storage/syp/sy-p-plus-cfg.json` , and then delete it, this configuration file will be automatically initialized the first time it is used.

In later releases, the release configuration will only be backward compatible to `1.6.0+`.

## Recent critical updates and bug fixes

- Support multiple publishing views, simple mode, detailed mode and source mode
- Support to modify summary, tags, classification, knowledge space
- The Hexo platform supports custom modification of YAML
- Yuque, Notion, and Hexo support image links, and automatic upload requires Picgo plugin support
- Zhihu platform supports automatic image upload
- When the Picgo plugin is not installed, some platforms can use the built-in image upload, such as Cnblogs, Typecho, WordPress
- Support replacing picture bed image links with Picgo plugin
- Fixed the issue that the release preview of the authorization code mode was invalidated
- Support publishing to Zhihu
- Support for publishing to Hexo
- Support for publishing to Notion
- Support for Yuque, Cnblogs, Metaweblog, Typecho, WordPress
- Support automatic generation of article aliases
- Support for changing the default knowledge base
**Front Row Announcement: the first AI-integrated version `1.10.0` of the Publish Tool is released!**

We recommend updating using the `uninstall->install` method. If there are any configuration issues, please back up `[workspace]/data/storage/syp/sy-p-plus-cfg.json`, then delete it, as this configuration file will be automatically initialized on first use.

## Recent Key Updates and Bug Fixes

- Support for manually generating titles, summaries, tags, and categories through AI.
- AI integration.
- Support for multiple publishing views: simple mode, detailed mode, and source code mode.
- Support for summaries, tags, categories, and knowledge spaces.
- Platforms that do not support image link replacement can use the platform's built-in image upload interface.
- Support for replacing image links with the Picgo plugin, if available.

## Platform List

Expand Down
26 changes: 5 additions & 21 deletions README_zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,18 @@

将思源笔记的文章发布到语雀、Notion、Cnblogs、WordPress、Typecho、Hexo、知乎 等平台,支持极速发布、图床管理、平台扩展、智能标签等特色功能。

> **前排公告1:发布工具首个支持发布视图以及AI公测尝鲜的版本 `1.9.0` 发布!**
>
> **前排公告2:发布工具完整支持图片上传的版本 `1.8.0` 发布!**
温馨提示:知乎使用知乎平台的图片上传,语雀、Notion、Hexo需要Picgo插件支持,Metaweblog系列平台同时支持Picgo插件和自带图片上传(安装了Picgo插件使用Picgo插件,否则使用自带)
> **前排公告:发布工具首个AI集成版本 `1.10.0` 发布!**
我们建议您使用 `卸载->安装` 方法进行更新。如果配置异常,请备份 `[workspace]/data/storage/syp/sy-p-plus-cfg.json` ,然后删除,这个配置文件会在第一次使用时自动初始化。

在更高版本中,发布配置将仅向后兼容到 `1.6.0+`

## 最近的关键更新与 Bug 修复

- 支持手动通过AI生成标题、摘要、标签、分类
- AI集成
- 支持多种发布视图,简单模式、详细模式和源码模式
- 支持修改摘要、标签、分类、知识空间
- Hexo 平台支持自定义修改 YAML
- 语雀、Notion、Hexo支持图片链接,自动上传需要Picgo插件支持
- 知乎平台支持图片自动上传
- 未安装Picgo插件时,部分平台可使用自带的图片上传,例如博客园、Typecho、WordPress
- 提供不支持图片链接替换的平台使用平台自带的图片上传接口
- 所有平台迁移到官方的正向代理,极大的提升性能
- 支持摘要、标签、分类、知识空间
- 不支持图片链接替换的平台支持使用平台自带的图片上传接口
- 支持使用Picgo插件的情况下替换图床图片链接
- 修复授权码模式发布预览失效问题
- 支持发布到知乎
- 支持发布到 Hexo
- 支持发布到 Notion
- 支持语雀、博客园、Metaweblog、Typecho、WordPress
- 支持自动生成文章别名
- 语雀支持更改默认知识库

## 平台列表

Expand Down
4 changes: 3 additions & 1 deletion siyuan/i18n/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@
"publishTo": "Publish to...",
"batchSync": "Batch sync",
"publishNormal": "Publish normal",
"extendFunction": "Extended functionality"
"extendFunction": "Extended functionality",
"aiChat": "AI chat",
"aiChatTab": "AI chat tab"
}
4 changes: 3 additions & 1 deletion siyuan/i18n/zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@
"publishTo": "一键发布",
"batchSync": "批量分发",
"publishNormal": "常规发布",
"extendFunction": "扩展功能"
"extendFunction": "扩展功能",
"aiChat": "AI聊天",
"aiChatTab": "AI聊天(Tab版)"
}
26 changes: 22 additions & 4 deletions siyuan/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* questions.
*/

import { App, getFrontend, IObject, Plugin } from "siyuan"
import { App, getFrontend, IModel, IObject, Plugin } from "siyuan"
import { SiyuanConfig, SiyuanKernelApi } from "zhi-siyuan-api"
import { createSiyuanAppLogger } from "./appLogger"
import { WidgetInvoke } from "./invoke/widgetInvoke"
Expand All @@ -32,12 +32,14 @@ import { Topbar } from "./topbar"
import "./index.styl"

export default class PublisherPlugin extends Plugin {
private logger
private topbar
private logger: any
private topbar: Topbar

public isMobile: boolean
public kernelApi: SiyuanKernelApi
private widgetInvoke
private widgetInvoke: WidgetInvoke
customTabObject: () => IModel
public tabInstance: any

constructor(options: { app: App; id: string; name: string; i18n: IObject }) {
super(options)
Expand All @@ -61,5 +63,21 @@ export default class PublisherPlugin extends Plugin {
onload() {
// 初始化菜单
this.topbar.initTopbar()
// 初始化自定义Tab
this.initCustomTab()
}

private initCustomTab() {
const that = this
this.customTabObject = this.addTab({
type: "publisher-plugin-custom-tab",
async init() {
this.element.innerHTML = `<p>加载中...</p>`
},
destroy() {
delete that.tabInstance
that.logger.info("publisher custopm tab destroyed")
},
})
}
}
47 changes: 46 additions & 1 deletion siyuan/invoke/widgetInvoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import PageUtil from "../utils/pageUtil"
import { showIframeDialog } from "../iframeDialog"
import PublisherPlugin from "../index"
import { StrUtil } from "zhi-common"
import { showMessage } from "siyuan"
import { openTab, showMessage } from "siyuan"

/**
* 挂件相关
Expand All @@ -56,6 +56,22 @@ export class WidgetInvoke {
await this.showPage(`/?id=${pageId}`)
}

public async showPublisherAiChatDialog() {
let pageId: string | undefined = PageUtil.getPageId()
if (pageId == "") {
pageId = undefined
}
await this.showPage(`/ai/chat?id=${pageId}`)
}

public async showPublisherAiChatTab() {
let pageId: string | undefined = PageUtil.getPageId()
if (pageId == "") {
pageId = undefined
}
this.showTab(`/ai/chat?id=${pageId}`)
}

public async showPublisherSinglePublishDialog() {
let pageId: string | undefined = PageUtil.getPageId()
if (pageId == "") {
Expand Down Expand Up @@ -120,4 +136,33 @@ export class WidgetInvoke {
showIframeDialog(this.pluginInstance, url, w, h, noscroll)
}
}

private showTab(pageUrl: string, noscroll?: boolean) {
// 自定义tab
this.pluginInstance.tabInstance = openTab({
app: this.pluginInstance.app,
custom: {
id: "publisher-ai-tab",
icon: "iconAccount",
title: this.pluginInstance.i18n.aiChatTab,
// @ts-expect-error
fn: this.pluginInstance.customTabObject,
},
})
const url = `/plugins/siyuan-plugin-publisher/#${pageUrl}`
this.logger.info("will show webview page =>", url)
// 有高度问题,参考下面的
// this.pluginInstance.tabInstance.panelElement.innerHTML = `
// <div class="plugin-publisher__custom-tab">
// <style>iframe { width: 100%; border: none; }</style>
// <iframe src="${url}" width="100%" scrolling="${noscroll ? "no" : "yes"}">
// </iframe>
// </div>`

// 参考 https://github.com/zuoez02/siyuan-plugin-webview-flomo/blob/main/index.js#L380C20-L382C29
this.pluginInstance.tabInstance.panelElement.innerHTML = `
<div style="display: flex" class="fn__flex-column fn__flex fn__flex-1 plugin-publisher__custom-tab">
<iframe allowfullscreen allowpopups style="border: none" class="fn__flex-column fn__flex fn__flex-1" src="${url}"></iframe>
</div>`
}
}
20 changes: 20 additions & 0 deletions siyuan/topbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,26 @@ export class Topbar {
},
})

// AI聊天
menu.addSeparator()
menu.addItem({
iconHTML: `<svg class="b3-menu__icon" style=""><use xlink:href="#iconUsers"></use></svg>`,
label: this.pluginInstance.i18n.aiChat,
click: () => {
this.widgetInvoke.showPublisherAiChatDialog()
},
})

// AI聊天Tab版
menu.addSeparator()
menu.addItem({
iconHTML: `<svg class="b3-menu__icon" style=""><use xlink:href="#iconAccount"></use></svg>`,
label: this.pluginInstance.i18n.aiChatTab,
click: () => {
this.widgetInvoke.showPublisherAiChatTab()
},
})

// 扩展功能
menu.addSeparator()
menu.addItem({
Expand Down
26 changes: 18 additions & 8 deletions src/components/publish/BatchPublishIndex.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,12 @@ import { IPublishCfg } from "~/src/types/IPublishCfg.ts"
import { PageEditMode } from "~/src/models/pageEditMode.ts"
import EditModeSelect from "~/src/components/publish/form/EditModeSelect.vue"
import PublishTime from "~/src/components/publish/form/PublishTime.vue"
import AiSwitch from "~/src/components/publish/form/AiSwitch.vue"
import { isDev } from "~/src/utils/constants.ts"
import { ICategoryConfig } from "~/src/types/ICategoryConfig.ts"
import { SiyuanAttr } from "zhi-siyuan-api"
import { DistributionPattern } from "~/src/models/distributionPattern.ts"
import _ from "lodash"
import PublishTitle from "~/src/components/publish/form/PublishTitle.vue"
import { useChatGPT } from "~/src/composables/useChatGPT.ts"
const logger = createAppLogger("publisher-index")
Expand Down Expand Up @@ -295,6 +294,17 @@ const handleRefresh = () => {
BrowserUtil.reloadPage()
}
const chckedChatGPTEnabled = () => {
let flag = false
try {
useChatGPT()
flag = true
} catch (e) {
logger.error(t("main.opt.failure") + "=>", e)
}
return flag
}
onMounted(async () => {
// ==================
// 初始化开始
Expand All @@ -311,7 +321,7 @@ onMounted(async () => {
// ==================
// 这里可以控制一些功能开关
formData.useAi = isDev
formData.useAi = chckedChatGPTEnabled()
formData.editType = PageEditMode.EditMode_simple
})
</script>
Expand Down Expand Up @@ -353,11 +363,11 @@ onMounted(async () => {
<div class="publish-form">
<el-form label-width="100px">
<el-alert
v-if="formData.useAi"
class="top-tip"
:title="t('category.ai.enabled')"
type="success"
:closable="false"
v-if="formData.useAi"
class="top-tip"
:title="t('category.ai.enabled')"
type="success"
:closable="false"
/>
<!-- 编辑模式选择 -->
<edit-mode-select v-model:edit-type="formData.editType" @emitSyncEditMode="syncEditMode" />
Expand Down
16 changes: 13 additions & 3 deletions src/components/publish/SinglePublishDoPublish.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,12 @@ import { PageEditMode } from "~/src/models/pageEditMode.ts"
import EditModeSelect from "~/src/components/publish/form/EditModeSelect.vue"
import PublishTime from "~/src/components/publish/form/PublishTime.vue"
import { isDev } from "~/src/utils/constants.ts"
import AiSwitch from "~/src/components/publish/form/AiSwitch.vue"
import { pre } from "~/src/utils/import/pre.ts"
import { ICategoryConfig } from "~/src/types/ICategoryConfig.ts"
import PublishKnowledgeSpace from "~/src/components/publish/form/PublishKnowledgeSpace.vue"
import { SiyuanAttr } from "zhi-siyuan-api"
import Adaptors from "~/src/adaptors"
import PublishTitle from "~/src/components/publish/form/PublishTitle.vue"
import { useChatGPT } from "~/src/composables/useChatGPT.ts"
const logger = createAppLogger("single-publish-do-publish")
Expand Down Expand Up @@ -355,6 +354,17 @@ const initPage = async () => {
}
}
const chckedChatGPTEnabled = () => {
let flag = false
try {
useChatGPT()
flag = true
} catch (e) {
logger.error(t("main.opt.failure") + "=>", e)
}
return flag
}
onMounted(async () => {
logger.info("获取到的ID为=>", id)
// ==================
Expand Down Expand Up @@ -392,7 +402,7 @@ onMounted(async () => {
// ==================
// 这里可以控制一些功能开关
formData.useAi = isDev
formData.useAi = chckedChatGPTEnabled()
formData.editType = PageEditMode.EditMode_simple
})
</script>
Expand Down
2 changes: 1 addition & 1 deletion src/components/publish/form/PublishDescription.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const handleMakeDesc = async () => {
// ElMessage.success(t("main.opt.success"))
} catch (e) {
logger.error(t("main.opt.failure") + "=>", e)
ElMessage.error(t("main.opt.failure") + "=>", e)
ElMessage.error(t("main.opt.failure") + "=>"+ e)
}
formData.isDescLoading = false
Expand Down
3 changes: 3 additions & 0 deletions src/components/set/GeneralSetting.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ const { t } = useVueI18n()
<el-tab-pane :label="t('service.tab.change.local')">
<preference-setting />
</el-tab-pane>
<el-tab-pane :label="t('sys.config.ai')">
<ai-setting />
</el-tab-pane>
<el-tab-pane :label="t('siyuan.config.setting')">
<siyuan-setting />
</el-tab-pane>
Expand Down
Loading

0 comments on commit c701ce6

Please sign in to comment.