Skip to content

Commit

Permalink
fix: 兼容平台图片上传-统一所有平台的预处理逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
terwer committed Aug 13, 2023
1 parent e5f10c4 commit 6d9aba3
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 97 deletions.
6 changes: 4 additions & 2 deletions src/adaptors/api/base/baseBlogApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { BlogApi, BlogConfig, Post } from "zhi-blog-api"
import { AppInstance } from "~/src/appInstance.ts"
import { createAppLogger, ILogger } from "~/src/utils/appLogger.ts"
import { useProxy } from "~/src/composables/useProxy.ts"
import { BaseExtendApi } from "~/src/adaptors/base/baseExtendApi.ts"

/**
* API授权统一封装基类
Expand All @@ -39,6 +40,7 @@ export class BaseBlogApi extends BlogApi {
protected logger: ILogger
protected cfg: BlogConfig
protected readonly proxyFetch: any
protected readonly baseExtendApi: BaseExtendApi

/**
* 初始化API授权适配器
Expand All @@ -51,14 +53,14 @@ export class BaseBlogApi extends BlogApi {

this.cfg = cfg
this.logger = createAppLogger("base-blog-api")
this.baseExtendApi = new BaseExtendApi(this)

const { proxyFetch } = useProxy(cfg.middlewareUrl)
this.proxyFetch = proxyFetch
}

public async preEditPost(post: Post, id?: string, publishCfg?: any): Promise<Post> {
this.logger.info("未处理,原样返回。如需处理,请在子类重写")
return post
return await this.baseExtendApi.preEditPost(post, id, publishCfg)
}

// ================
Expand Down
32 changes: 1 addition & 31 deletions src/adaptors/api/cnblogs/cnblogsApiAdaptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,12 @@
* questions.
*/

import {MediaObject, Post, UserBlog} from "zhi-blog-api"
import { Post, UserBlog } from "zhi-blog-api"
import { CnblogsConfig } from "~/src/adaptors/api/cnblogs/cnblogsConfig.ts"
import { AppInstance } from "~/src/appInstance.ts"
import { createAppLogger } from "~/src/utils/appLogger.ts"
import { CnblogsConstants } from "~/src/adaptors/api/cnblogs/cnblogsConstants.ts"
import { MetaweblogBlogApiAdaptor } from "~/src/adaptors/api/base/metaweblog/metaweblogBlogApiAdaptor.ts"
import {usePicgoBridge} from "~/src/composables/usePicgoBridge.ts";

/**
* 博客园 API 适配器
Expand Down Expand Up @@ -64,35 +63,6 @@ class CnblogsApiAdaptor extends MetaweblogBlogApiAdaptor {
return result
}

public async preEditPost(post: Post, id?: string, publishCfg?: any): Promise<Post> {
// const pubCfg = publishCfg as IPublishCfg
// 找到所有的图片
const { getImageItemsFromMd } = usePicgoBridge()
const images = await getImageItemsFromMd(id, post.markdown)
if (images.length === 0) {
this.logger.info("未找到图片,不处理")
return post
}
// 批量处理图片上传
this.logger.info(`找到${images.length}张图片,开始上传`)

for (const image of images) {
const imageBlob = await this.readFileToBlob(image.url)
this.logger.debug("read blob from image", { imageBlob })
const file = new File([imageBlob], image.name, { type: imageBlob.type, lastModified: Date.now() })
this.logger.debug("convert blob to file", { imageBlob })

const mediaObject = new MediaObject(image.name, imageBlob.type, file as any)
const attachResult = await this.newMediaObject(mediaObject)
this.logger.debug("attachResult =>", attachResult)
throw new Error("开发中")
}

this.logger.info("图片全部上传完成")
return post
}


public async newPost(post: Post, publish?: boolean): Promise<string> {
// 设置markdown分类
post = this.assignMdCategory(post)
Expand Down
101 changes: 101 additions & 0 deletions src/adaptors/base/baseExtendApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* 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, youweics@163.com
* or visit www.terwer.space if you need additional information or have any
* questions.
*/

import { IBlogApi } from "zhi-blog-api/dist/lib/IBlogApi"
import { IWebApi } from "zhi-blog-api/dist/lib/IWebApi"
import { BaseBlogApi } from "~/src/adaptors/api/base/baseBlogApi.ts"
import { BaseWebApi } from "~/src/adaptors/web/base/baseWebApi.ts"
import { MediaObject, Post, WebApi } from "zhi-blog-api"
import { createAppLogger, ILogger } from "~/src/utils/appLogger.ts"
import { CommonBlogConfig } from "~/src/adaptors/api/base/commonBlogConfig.ts"
import { LuteUtil } from "~/src/utils/luteUtil.ts"
import { usePicgoBridge } from "~/src/composables/usePicgoBridge.ts"
import { base64ToBuffer, remoteImageToBase64Info } from "~/src/utils/polyfillUtils.ts"

/**
* 各种模式共享的扩展基类
*
* @author terwer
* @since 1.8.0
*/
class BaseExtendApi extends WebApi implements IBlogApi, IWebApi {
private readonly logger: ILogger
private readonly api: BaseBlogApi | BaseWebApi
protected readonly picgoBridge: any

constructor(api: BaseBlogApi | BaseWebApi) {
super()
this.logger = createAppLogger("base-extend-api")
this.api = api

this.picgoBridge = usePicgoBridge()
}

public async preEditPost(post: Post, id?: string, publishCfg?: any): Promise<Post> {
const cfg: CommonBlogConfig = publishCfg.cfg

// const unsupportedPicturePlatform = ["custom_Zhihu","common_notion"],判断key包含zhihu、notion,custom_Zhihu 或者 /custom_Zhihu-\w+/
// PictureStoreTypeEnum.Picgo 如果设置了图片存储方式 PicGO图床 类型就使用 PicGO图床 上传
// PictureStoreTypeEnum.Platform or key in unsupportedPicturePlatform 如果设置了图片存储方式为 平台存储 类型或者 知乎、Notion等不兼容链接方式的平台,就使用 平台特定的存储方式 上传
// PictureStoreTypeEnum.Default 默认不处理,即使用 思源笔记图床 上传

// ==========================
// 使用 PicGO上传图片
// ==========================
// 图片替换
this.logger.debug("开始图片处理, post =>", { post })
post.markdown = await this.picgoBridge.handlePicgo(id, post.markdown)
// 利用 lute 把 md 转换成 html
post.html = LuteUtil.mdToHtml(post.markdown)
this.logger.debug("图片处理完毕, post.markdown =>", { md: post.markdown })

// ==========================
// 使用平台上传图片
// ==========================
// 找到所有的图片
const images = await this.picgoBridge.getImageItemsFromMd(id, post.markdown)
if (images.length === 0) {
this.logger.info("未找到图片,不处理")
return post
}
// 批量处理图片上传
this.logger.info(`找到${images.length}张图片,开始上传`)
for (const image of images) {
const imageUrl = image.url
const base64Info = await remoteImageToBase64Info(imageUrl)
const bits = base64ToBuffer(base64Info.imageBase64)
const mediaObject = new MediaObject(image.name, base64Info.mimeType, bits)
this.logger.debug("before upload, mediaObject =>", mediaObject)
const attachResult = await this.newMediaObject(mediaObject)
this.logger.debug("attachResult =>", attachResult)
throw new Error("开发中")
}

this.logger.info("图片全部上传完成")
return post
}
}

export { BaseExtendApi }
6 changes: 4 additions & 2 deletions src/adaptors/web/base/baseWebApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { Attachment, ElectronCookie, MediaObject, Post, WebApi, WebConfig } from
import { AppInstance } from "~/src/appInstance.ts"
import { createAppLogger, ILogger } from "~/src/utils/appLogger.ts"
import { useProxy } from "~/src/composables/useProxy.ts"
import { BaseExtendApi } from "~/src/adaptors/base/baseExtendApi.ts"

/**
* 网页授权统一封装基类
Expand All @@ -38,6 +39,7 @@ class BaseWebApi extends WebApi {
protected logger: ILogger
protected cfg: WebConfig
protected readonly proxyFetch: any
protected readonly baseExtendApi: BaseExtendApi

/**
* 初始化网页授权 API 适配器
Expand All @@ -50,6 +52,7 @@ class BaseWebApi extends WebApi {

this.cfg = cfg
this.logger = createAppLogger("base-web-api")
this.baseExtendApi = new BaseExtendApi(this)

const { proxyFetch } = useProxy(cfg.middlewareUrl)
this.proxyFetch = proxyFetch
Expand All @@ -66,8 +69,7 @@ class BaseWebApi extends WebApi {
}

public async preEditPost(post: Post, id?: string, publishCfg?: any): Promise<Post> {
this.logger.info("未处理,原样返回。如需处理,请在子类重写")
return post
return await this.baseExtendApi.preEditPost(post, id, publishCfg)
}

// 兼容的方法
Expand Down
36 changes: 2 additions & 34 deletions src/adaptors/web/zhihu/zhihuWebAdaptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@
*/

import { BaseWebApi } from "~/src/adaptors/web/base/baseWebApi.ts"
import { MediaObject, Post, UserBlog } from "zhi-blog-api"
import { Post, UserBlog } from "zhi-blog-api"
import * as cheerio from "cheerio"
import { JsonUtil, StrUtil } from "zhi-common"
import { usePicgoBridge } from "~/src/composables/usePicgoBridge.ts"
import { IPublishCfg } from "~/src/types/IPublishCfg.ts"
import { base64ToBuffer, remoteImageToBase64Info } from "~/src/utils/polyfillUtils.ts"

/**
* 知乎网页授权适配器
Expand Down Expand Up @@ -98,36 +95,6 @@ class ZhihuWebAdaptor extends BaseWebApi {
return result
}

public async preEditPost(post: Post, id?: string, publishCfg?: any): Promise<Post> {
const pubCfg = publishCfg as IPublishCfg
const cfg = pubCfg.cfg

const { getImageItemsFromMd } = usePicgoBridge()

// 找到所有的图片
const images = await getImageItemsFromMd(id, post.markdown)
if (images.length === 0) {
this.logger.info("未找到图片,不处理")
return post
}
// 批量处理图片上传
this.logger.info(`找到${images.length}张图片,开始上传`)

for (const image of images) {
const imageUrl = image.url
const base64Info = await remoteImageToBase64Info(imageUrl)
const bits = base64ToBuffer(base64Info.imageBase64)
const mediaObject = new MediaObject(image.name, base64Info.mimeType, bits)
this.logger.debug("before upload, mediaObject =>", mediaObject)
const attachResult = await this.newMediaObject(mediaObject)
this.logger.debug("attachResult =>", attachResult)
throw new Error("开发中")
}

this.logger.info("图片全部上传完成")
return post
}

public async addPost(post: Post) {
const params = JSON.stringify({
title: post.title,
Expand Down Expand Up @@ -258,6 +225,7 @@ class ZhihuWebAdaptor extends BaseWebApi {
public async uploadFile(file: File): Promise<any> {
this.logger.debug("zhihu start uploadFile =>", file)

throw new Error("开发中=>zhihu uploadFile")
return {}
}
}
Expand Down
29 changes: 1 addition & 28 deletions src/composables/usePublish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import { IPublishCfg } from "~/src/types/IPublishCfg.ts"
import { usePublishConfig } from "~/src/composables/usePublishConfig.ts"
import { ElMessage } from "element-plus"
import { usePicgoBridge } from "~/src/composables/usePicgoBridge.ts"
import { LuteUtil } from "~/src/utils/luteUtil.ts"

/**
* 通用发布组件
Expand All @@ -56,7 +55,6 @@ const usePublish = () => {
const { updateSetting } = useSettingStore()
const { kernelApi, blogApi } = useSiyuanApi()
const { getPublishApi } = usePublishConfig()
const { handlePicgo } = usePicgoBridge()

// datas
const singleFormData = reactive({
Expand Down Expand Up @@ -113,19 +111,14 @@ const usePublish = () => {
// 分配文章属性 - 初始化和发布都会调用
post = await assignAttrs(post, id, publishCfg)

// 全局正文预处理 - 仅在发布的时候调用
logger.debug(`before preHandlePost, isAdd ${singleFormData.isAdd}, doc=>`, toRaw(post))
post = await preHandlePost(post, id, publishCfg)
logger.debug(`after preHandlePost, post=>`, toRaw(post))

// ===================================
// 文章处理结束
// ===================================

// 初始化API
const api = await getPublishApi(key, cfg)

// 平台相关的预处理 - 仅在发布的时候调用
// 平台相关的正文预处理 - 仅在发布的时候调用
logger.debug(`before preEditPost, isAdd ${singleFormData.isAdd}, post=>`, toRaw(post))
post = await api.preEditPost(post, id, publishCfg)
logger.debug(`after preEditPost, post=>`, toRaw(post))
Expand Down Expand Up @@ -311,26 +304,6 @@ const usePublish = () => {
return isAbsoluteUrl ? previewUrl : `${cfg?.home ?? ""}${previewUrl}`
}

/**
* 文章预处理 - 仅在发布的时候调用
*
* @param post - 文章对象
* @param id - 思源笔记文档ID
* @param publishCfg - 发布配置
*/
const preHandlePost = async (post: Post, id: string, publishCfg: IPublishCfg): Promise<Post> => {
const cfg: CommonBlogConfig = publishCfg.cfg

// 图片替换
logger.debug("开始图片处理, post =>", { post })
post.markdown = await handlePicgo(id, post.markdown)
// 利用 lute 把 md 转换成 html
post.html = LuteUtil.mdToHtml(post.markdown)
logger.debug("图片处理完毕, post.markdown =>", { md: post.markdown })

return post
}

// const assignCompareValue = (title1: string, title2: string) => (title1.length > title2.length ? title1 : title2)

/**
Expand Down

0 comments on commit 6d9aba3

Please sign in to comment.