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 65a30dd commit c512e93
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 54 deletions.
2 changes: 1 addition & 1 deletion README_zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

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

- 所有平台迁移到官方的正向代理
- 所有平台迁移到官方的正向代理,极大的提升性能
- 支持使用Picgo插件的情况下替换图床图片链接
- 修复授权码模式发布预览失效问题
- 支持发布到知乎
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"zhi-blog-api": "^1.20.21",
"zhi-common": "^1.14.2",
"zhi-device": "^2.3.0",
"zhi-fetch-middleware": "^0.2.20",
"zhi-fetch-middleware": "^0.2.21",
"zhi-github-middleware": "^0.2.2",
"zhi-lib-base": "^0.4.4",
"zhi-notion-markdown": "^0.1.2",
Expand Down
18 changes: 9 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 0 additions & 7 deletions src/adaptors/api/base/baseBlogApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,4 @@ export class BaseBlogApi extends BlogApi {
// ================
// private methods
// ================
public async readFileToBlob(url: string) {
const response = await this.proxyFetch(url, [], {}, "GET", "image/jpeg")
const body = response.body
const blobData = new Blob([body], { type: response.contentType })
this.logger.debug("blobData =>", blobData)
return blobData
}
}
24 changes: 9 additions & 15 deletions src/adaptors/web/base/baseWebApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,40 +81,34 @@ class BaseWebApi extends WebApi {

public async newMediaObject(mediaObject: MediaObject, customHandler?: any): Promise<Attachment> {
const bits = mediaObject.bits
const res = await this.uploadFile(bits as any)
const blob = new Blob([bits], { type: mediaObject.type })
const res = await this.uploadFile(blob as File)
return {
attachment_id: res?.id,
date_created_gmt: new Date(),
parent: 0,
link: res?.url,
title: "20220616-132401-001.jpg",
title: mediaObject.name,
caption: "",
description: "",
metadata: {
width: 0,
height: 0,
file: "",
filesize: 113032,
filesize: 0,
sizes: [],
},
type: "image/jpeg",
thumbnail: "https://terwergreen.files.wordpress.com/2022/06/20220616-132401-001.jpg?w=150",
id: "4108",
file: "20220616-132401-001.jpg",
url: "http://terwergreen.files.wordpress.com/2022/06/20220616-132401-001.jpg",
type: mediaObject.type,
thumbnail: "",
id: res?.article_id,
file: mediaObject.name,
url: res.url,
}
}

// ================
// private methods
// ================
public async readFileToBlob(url: string) {
const response = await this.proxyFetch(url, [], {}, "GET", "image/jpeg")
const body = response.body
const blobData = new Blob([body], { type: response.contentType })
this.logger.debug("blobData =>", blobData)
return blobData
}
}

export { BaseWebApi }
25 changes: 16 additions & 9 deletions src/adaptors/web/zhihu/zhihuWebAdaptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ 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 { useProxy } from "~/src/composables/useProxy.ts"
import { blobToBuffer } from "~/src/utils/polyfillUtils.ts"

/**
* 知乎网页授权适配器
Expand Down Expand Up @@ -98,9 +100,13 @@ class ZhihuWebAdaptor extends BaseWebApi {
}

public async preEditPost(post: Post, id?: string, publishCfg?: any): Promise<Post> {
// const pubCfg = publishCfg as IPublishCfg
// 找到所有的图片
const pubCfg = publishCfg as IPublishCfg
const cfg = pubCfg.cfg

const { getImageItemsFromMd } = usePicgoBridge()
const { proxyBlob } = useProxy(cfg.middlewareUrl)

// 找到所有的图片
const images = await getImageItemsFromMd(id, post.markdown)
if (images.length === 0) {
this.logger.info("未找到图片,不处理")
Expand All @@ -110,12 +116,11 @@ class ZhihuWebAdaptor extends BaseWebApi {
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 imageUrl = image.url
const imageBlob = await proxyBlob(imageUrl)
const bits = await blobToBuffer(imageBlob)
const mediaObject = new MediaObject(image.name, imageBlob.type, bits)
this.logger.debug("before upload, mediaObject =>", mediaObject)
const attachResult = await this.newMediaObject(mediaObject)
this.logger.debug("attachResult =>", attachResult)
throw new Error("开发中")
Expand Down Expand Up @@ -253,7 +258,9 @@ class ZhihuWebAdaptor extends BaseWebApi {
}

public async uploadFile(file: File): Promise<any> {
return await super.uploadFile(file)
this.logger.debug("zhihu start uploadFile =>", file)

return {}
}
}

Expand Down
38 changes: 31 additions & 7 deletions src/components/test/CnblogsTest.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@
import { AppInstance } from "~/src/appInstance.ts"
import { Utils } from "~/src/utils/utils.ts"
import { reactive, ref } from "vue"
import { fileToBuffer } from "~/src/utils/polyfillUtils.ts"
import { MediaObject, Post } from "zhi-blog-api"
import { createAppLogger } from "~/src/utils/appLogger.ts"
import Adaptors from "~/src/adaptors"
import { useVueI18n } from "~/src/composables/useVueI18n.ts"
import { useProxy } from "~/src/composables/useProxy.ts"
import { blobToBuffer, fileToBuffer, toBuffer } from "~/src/utils/polyfillUtils.ts"

Check failure on line 35 in src/components/test/CnblogsTest.vue

View workflow job for this annotation

GitHub Actions / ci

Module '"~/src/utils/polyfillUtils.ts"' has no exported member 'toBuffer'.
const logger = createAppLogger("cnblogs-test")
Expand Down Expand Up @@ -306,21 +307,44 @@ const cnblogsHandleApi = async () => {
break
}
case METHOD_NEW_MEDIA_OBJECT: {
const key = "metaweblog_Cnblogs"
// const key = "metaweblog_Cnblogs"
//
// const file = paramFile.value
// const bits = await fileToBuffer(file)
// const mediaObject = new MediaObject(file.name, file.type, bits)
// logger.info("mediaObject=>", mediaObject)
//
// // 设置文件的元数据
// const cnblogsApiAdaptor = await Adaptors.getAdaptor(key)
// const cnblogsApi = Utils.blogApi(appInstance, cnblogsApiAdaptor)
// logger.info("cnblogsApi=>", cnblogsApi)
// const result = await cnblogsApi.newMediaObject(mediaObject)
// logMessage.value = JSON.stringify(result)
// logger.info("cnblogs new mediaObject result=>", result)
const file = paramFile.value
const bits = await fileToBuffer(file)
const mediaObject = new MediaObject(file.name, file.type, bits)
logger.info("mediaObject=>", mediaObject)
// upload url
const key = "metaweblog_Cnblogs"
// 设置文件的元数据
const cnblogsApiAdaptor = await Adaptors.getAdaptor(key)
const cfg = await Adaptors.getCfg(key)
const cnblogsApi = Utils.blogApi(appInstance, cnblogsApiAdaptor)
const { proxyBlob } = useProxy(cfg.middlewareUrl)
logger.info("cnblogsApi=>", cnblogsApi)
const imageUrl = "https://static-rs-terwer.oss-cn-beijing.aliyuncs.com/test/image-20230812091531-hibwr1g.png"
const imageName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1)
const imageBlob = await proxyBlob(imageUrl)
const bits = await blobToBuffer(imageBlob)
logger.debug("bits=>", bits)
const mediaObject = new MediaObject(imageName, "image/png", bits)
logger.info("mediaObject=>", mediaObject)
const result = await cnblogsApi.newMediaObject(mediaObject)
logMessage.value = JSON.stringify(result)
logger.info("cnblogs new mediaObject result=>", result)
// SimpleXmlRpcClient
// const key = "metaweblog_Cnblogs"
//
// const file = paramFile.value
Expand All @@ -341,7 +365,7 @@ const cnblogsHandleApi = async () => {
// logMessage.value = JSON.stringify(result)
// logger.info("cnblogs new mediaObject result=>", result)
// proxy
// proxyXmlrpc
// const key = "metaweblog_Cnblogs"
// const cfg = await Adaptors.getCfg(key)
// const { proxyXmlrpc } = useProxy(cfg.middlewareUrl)
Expand Down
29 changes: 24 additions & 5 deletions src/composables/useProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ const useProxy = (middlewareUrl?: string) => {
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" = "GET",
contentType: string = "application/json"
) => {
if (isUseSiyuanProxy) {
logger.info("Using Siyuan forwardProxy")
const siyuanSupported = ["application/json", "text/html", "text/xml"]
if (isUseSiyuanProxy && siyuanSupported.includes(contentType)) {
logger.info("Using Siyuan forwardProxy, contentType=>", contentType)
let body: any
if (typeof params === "string" && !StrUtil.isEmptyString(params)) {
body = params
Expand All @@ -95,8 +96,12 @@ const useProxy = (middlewareUrl?: string) => {
} else if (contentType === "text/html") {
const resText = fetchResult?.body
return resText
} else if (contentType === "text/xml") {
const resText = fetchResult?.body
return resText
} else {
return fetchResult
logger.error("SiYuan proxy not supported for content type:", contentType)
throw new Error("SiYuan proxy not supported for content type:" + contentType)
}
} else {
logger.info("Using middleware proxy")
Expand Down Expand Up @@ -126,15 +131,29 @@ const useProxy = (middlewareUrl?: string) => {
const proxyXmlrpc = async (url: string, reqMethod: string, reqParams: any[]) => {
const body = serializer.serializeMethodCall(reqMethod, reqParams)
const res = await proxyFetch(url, [], body, "POST", "text/xml")
let resText = res.body
let resText = res
resText = XmlrpcUtil.removeXmlHeader(resText)
const deserializer = new Deserializer()
const resJson = await deserializer.deserializeMethodResponse(resText)
logger.debug("xmlrpc fetch result, resJson =>", resJson)
return resJson
}

return { proxyFetch, proxyXmlrpc }
/**
* 使用代理请求获取 Blob 数据
*
* @param url - 请求的 URL
* @returns 返回请求的 Blob 数据
*/
const proxyBlob = async (url: string): Promise<Blob> => {
const contentType = "image/png"
const response = await proxyFetch(url, [], {}, "GET", contentType)
const ab = await response.arrayBuffer()
logger.debug("arrayBuffer =>", ab)
return new Blob([ab], { type: contentType })
}

return { proxyFetch, proxyXmlrpc, proxyBlob }
}

export { useProxy }
16 changes: 16 additions & 0 deletions src/utils/polyfillUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,19 @@ export const fileToBuffer = async (file: any): Promise<any> => {
reader.readAsArrayBuffer(file)
})
}

export const blobToBuffer = (blob: Blob): Promise<Buffer> => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onloadend = () => {
if (reader.readyState === FileReader.DONE) {
const arrayBuffer = reader.result as ArrayBuffer
const buffer = Buffer.from(arrayBuffer)
resolve(buffer)
} else {
reject(new Error("Failed to convert Blob to Buffer."))
}
}
reader.readAsArrayBuffer(blob)
})
}

0 comments on commit c512e93

Please sign in to comment.