Skip to content

Commit

Permalink
feat: #130 支持发布到CSDN-支持CSDN图床
Browse files Browse the repository at this point in the history
  • Loading branch information
terwer committed Sep 2, 2023
1 parent 0e7eb52 commit 1a13e49
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 43 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@
"vue-i18n": "^9.2.2",
"vue-router": "^4.2.4",
"xmlbuilder2": "^3.1.1",
"zhi-blog-api": "^1.36.2",
"zhi-blog-api": "^1.36.3",
"zhi-common": "^1.23.7",
"zhi-device": "^2.3.1",
"zhi-fetch-middleware": "^0.6.4",
"zhi-github-middleware": "^0.4.2",
"zhi-gitlab-middleware": "^0.6.4",
"zhi-lib-base": "^0.5.0",
"zhi-notion-markdown": "^0.1.4",
"zhi-siyuan-api": "^2.7.3",
"zhi-siyuan-api": "^2.7.4",
"zhi-xmlrpc-middleware": "^0.5.11"
}
}
20 changes: 10 additions & 10 deletions pnpm-lock.yaml

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

2 changes: 1 addition & 1 deletion src/adaptors/web/base/baseWebApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class BaseWebApi extends WebApi {
const bits = mediaObject.bits
this.logger.debug("newMediaObject on baseWebApi =>", mediaObject)
const blob = new Blob([bits], { type: mediaObject.type })
const res = await this.uploadFile(blob as File)
const res = await this.uploadFile(blob as File, mediaObject.name)
return {
attachment_id: res?.id,
date_created_gmt: new Date(),
Expand Down
76 changes: 75 additions & 1 deletion src/adaptors/web/csdn/csdnWebAdaptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import { BaseWebApi } from "~/src/adaptors/web/base/baseWebApi.ts"
import CsdnUtils from "~/src/adaptors/web/csdn/csdnUtils.ts"
import { CategoryInfo, Post, UserBlog } from "zhi-blog-api"
import { StrUtil } from "zhi-common"
import { JsonUtil, StrUtil } from "zhi-common"
import WebUtils from "~/src/adaptors/web/base/webUtils.ts"

/**
Expand Down Expand Up @@ -271,9 +271,83 @@ class CsdnWebAdaptor extends BaseWebApi {
return flag
}

public async uploadFile(file: File | Blob, filename?: string): Promise<any> {
this.logger.debug(`csdn start uploadFile ${filename}=>`, file)
if (file instanceof Blob) {
const uploadData = await this.requestUpload(filename)
this.logger.debug("csdn image uploadData =>", uploadData)
if (!uploadData) {
throw new Error("CSDN图片信息获取失败 =>" + filename)
}

const uploadUrl = uploadData.host
const formData = new FormData()
formData.append("key", uploadData.filePath)
formData.append("policy", uploadData.policy)
formData.append("OSSAccessKeyId", uploadData.accessId)
formData.append("success_action_status", "200")
formData.append("signature", uploadData.signature)
formData.append("callback", uploadData.callbackUrl)
formData.append("file", file)

this.logger.debug("csdn image upload strat...")
const response = await fetch(uploadUrl, {
method: "POST",
body: formData,
})
const resText = await response.text()
this.logger.debug("csdn image upload success, resText=>", resText)
const resJson = JsonUtil.safeParse<any>(resText, {} as any)
if (resJson.code !== 200) {
throw new Error("CSDN图片上传失败 =>" + filename)
}
return {
id: resJson.data.targetObjectKey,
object_key: resJson.data.targetObjectKeyy,
url: resJson.data.imageUrl,
}

// 其他方式,待研究。上面的仅PC客户端可用
// var res = await this.csdnFetch(uploadUrl, [], params, "POST", "multipart/form-data")
// this.logger.debug("csdn image upload success, res=>", res)
}

return {}
}
// ================
// private methods
// ================
private async requestUpload(filename: string) {
const api = "https://imgservice.csdn.net/direct/v1.0/image/upload?watermark=&type=blog&rtype=markdown"
const fileExt = filename.split(".").pop()
if (!this.validateFileExt(fileExt)) {
return null
}

var res = await this.csdnFetch(api, {
"x-image-app": "direct_blog",
"x-image-suffix": fileExt,
"x-image-dir": "direct",
})
if (res.code !== 200) {
this.logger.error("图片可能已经上传,信息如下", res)
return null
}
return res.data
}

private validateFileExt(ext: string): boolean {
switch (ext.toLowerCase()) {
case "jpg":
case "png":
case "jpeg":
case "gif":
return true
default:
return false
}
}

private async csdnFetch(
url: string,
headers: any = {},
Expand Down
53 changes: 25 additions & 28 deletions src/adaptors/web/zhihu/zhihuWebAdaptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,33 +230,8 @@ class ZhihuWebAdaptor extends BaseWebApi {
return cats
}

// ================
// private methods
// ================
/**
* 收录文章到专栏
*
* @param columnId - 专栏ID
* @param articleId - 文章ID
* @private
*/
private async addPostToColumn(columnId: string, articleId: string) {
if (StrUtil.isEmptyString(columnId) || StrUtil.isEmptyString(articleId)) {
this.logger.info("文章或者专栏为空,不收录")
return
}

try {
const params = { type: "article", id: articleId }
await this.webProxyFetch(`https://www.zhihu.com/api/v4/columns/${columnId}/items`, [], params, "POST")
} catch (e) {
this.logger.error("文章收录到专栏失败", e)
}
this.logger.info("文章收录到专栏成功")
}

public async uploadFile(file: File | Blob): Promise<any> {
this.logger.debug("zhihu start uploadFile =>", file)
public async uploadFile(file: File | Blob, filename?: string): Promise<any> {
this.logger.debug(`zhihu start uploadFile ${filename}=>`, file)
if (file instanceof Blob) {
// 1. 获取图片hash
const ab = await file.arrayBuffer()
Expand All @@ -272,7 +247,7 @@ class ZhihuWebAdaptor extends BaseWebApi {
const fileResp = await this.webProxyFetch("https://api.zhihu.com/images", [], params, "POST")
this.logger.debug("zhihu uploadFile, fileResp =>", fileResp)

// 开始上传
// 2. 开始上传
const upload_file = fileResp.upload_file
if (fileResp.upload_file.state == 1) {
const imgDetail = await this.untilImageDone(upload_file.image_id)
Expand Down Expand Up @@ -309,6 +284,28 @@ class ZhihuWebAdaptor extends BaseWebApi {
// ================
// private methods
// ================
/**
* 收录文章到专栏
*
* @param columnId - 专栏ID
* @param articleId - 文章ID
* @private
*/
private async addPostToColumn(columnId: string, articleId: string) {
if (StrUtil.isEmptyString(columnId) || StrUtil.isEmptyString(articleId)) {
this.logger.info("文章或者专栏为空,不收录")
return
}

try {
const params = { type: "article", id: articleId }
await this.webProxyFetch(`https://www.zhihu.com/api/v4/columns/${columnId}/items`, [], params, "POST")
} catch (e) {
this.logger.error("文章收录到专栏失败", e)
}
this.logger.info("文章收录到专栏成功")
}

private async untilImageDone(image_id: string): Promise<any> {
const that = this
return new Promise(function (resolve, reject) {
Expand Down
2 changes: 1 addition & 1 deletion src/composables/useProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const useProxy = (middlewareUrl?: string) => {
const fetchOptions = {
method: method,
headers: {
"Content-Type": "application/json",
"Content-Type": contentType,
...header,
},
}
Expand Down

0 comments on commit 1a13e49

Please sign in to comment.