Skip to content

Commit

Permalink
feat: 支持简书和掘金
Browse files Browse the repository at this point in the history
  • Loading branch information
terwer committed Sep 6, 2023
1 parent a974df1 commit 3c3e49e
Show file tree
Hide file tree
Showing 21 changed files with 613 additions and 70 deletions.
4 changes: 2 additions & 2 deletions src/adaptors/api/notion/notionApiAdaptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@ class NotionApiAdaptor extends BaseBlogApi {
* @private postid
*/
private getNotionPostidKey(postid: string): any {
let pageId
let endUrl
let pageId: string
let endUrl: string
if (postid.indexOf("_") > 0) {
const idArr = postid.split("_")
pageId = idArr[0]
Expand Down
4 changes: 2 additions & 2 deletions src/adaptors/api/yuque/yuqueApiAdaptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ class YuqueApiAdaptor extends BaseBlogApi {
* @private postid
*/
private getYuquePostidKey(postid: string): any {
let docId
let docRepo
let docId: string
let docRepo: string
if (postid.indexOf("_") > 0) {
const idArr = postid.split("_")
docId = idArr[0]
Expand Down
42 changes: 22 additions & 20 deletions src/adaptors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import { useHexoApi } from "~/src/adaptors/api/hexo/useHexoApi.ts"
import { useGitlabhexoApi } from "~/src/adaptors/api/gitlab-hexo/useGitlabhexoApi.ts"
import { useCsdnWeb } from "~/src/adaptors/web/csdn/useCsdnWeb.ts"
import { useWechatWeb } from "~/src/adaptors/web/wechat/useWechatWeb.ts"
import {useJianshuWeb} from "~/src/adaptors/web/jianshu/useJianshuWeb.ts";
import {useJuejinWeb} from "~/src/adaptors/web/juejin/useJuejinWeb.ts";

/**
* 适配器统一入口
Expand Down Expand Up @@ -114,16 +116,16 @@ class Adaptors {
conf = cfg
break
}
// case SubPlatformType.Custom_Jianshu: {
// const { cfg } = await useJianshuWeb(key)
// conf = cfg
// break
// }
// case SubPlatformType.Custom_Juejin: {
// const { cfg } = await useJuejinWeb(key)
// conf = cfg
// break
// }
case SubPlatformType.Custom_Jianshu: {
const { cfg } = await useJianshuWeb(key)
conf = cfg
break
}
case SubPlatformType.Custom_Juejin: {
const { cfg } = await useJuejinWeb(key)
conf = cfg
break
}
case SubPlatformType.System_Siyuan: {
const { siyuanConfig } = useSiyuanApi()
conf = siyuanConfig
Expand Down Expand Up @@ -204,16 +206,16 @@ class Adaptors {
blogAdaptor = webApi
break
}
// case SubPlatformType.Custom_Jianshu: {
// const { webApi } = await useJianshuWeb(key, newCfg)
// blogAdaptor = webApi
// break
// }
// case SubPlatformType.Custom_Juejin: {
// const { webApi } = await useJuejinWeb(key, newCfg)
// blogAdaptor = webApi
// break
// }
case SubPlatformType.Custom_Jianshu: {
const { webApi } = await useJianshuWeb(key, newCfg)
blogAdaptor = webApi
break
}
case SubPlatformType.Custom_Juejin: {
const { webApi } = await useJuejinWeb(key, newCfg)
blogAdaptor = webApi
break
}
case SubPlatformType.System_Siyuan: {
const { blogApi } = useSiyuanApi()
blogAdaptor = blogApi
Expand Down
16 changes: 15 additions & 1 deletion src/adaptors/web/jianshu/jianshuConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,26 @@
*/

import { CommonWebConfig } from "~/src/adaptors/web/base/commonWebConfig.ts"
import { CategoryTypeEnum, PageTypeEnum, PasswordType } from "zhi-blog-api"

/**
* 简书配置
*/
export class JianshuConfig extends CommonWebConfig {
constructor(username: string, password: string, middlewareUrl?: string) {
super("", "", username, password, middlewareUrl)
super("https://www.jianshu.com", "https://www.jianshu.com", username, password, middlewareUrl)

this.previewUrl = "/p/[postid]"
this.pageType = PageTypeEnum.Markdown
this.passwordType = PasswordType.PasswordType_Cookie
this.usernameEnabled = false
this.tagEnabled = false
this.cateEnabled = false
this.knowledgeSpaceEnabled = true
this.knowledgeSpaceTitle = "笔记本"
this.knowledgeSpaceType = CategoryTypeEnum.CategoryType_Single
this.allowKnowledgeSpaceChange = false
this.placeholder.knowledgeSpaceReadonlyModeTip =
"由于简书平台的限制,暂时不支持编辑所属笔记本。如果您想移动文档,请先点击取消删除该文档,然后重新选择新的笔记本发布"
}
}
30 changes: 30 additions & 0 deletions src/adaptors/web/jianshu/jianshuPlaceholder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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 { CommonWebPlaceholder } from "~/src/adaptors/web/base/commonWebPlaceholder.ts"

class JianshuPlaceholder extends CommonWebPlaceholder {}

export { JianshuPlaceholder }
196 changes: 193 additions & 3 deletions src/adaptors/web/jianshu/jianshuWebAdaptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
*/

import { BaseWebApi } from "~/src/adaptors/web/base/baseWebApi.ts"
import { CategoryInfo, Post, UserBlog } from "zhi-blog-api"
import * as cheerio from "cheerio"
import { JsonUtil, StrUtil } from "zhi-common"
import { ElMessage } from "element-plus"

/**
* 简书网页授权适配器
Expand All @@ -35,8 +39,7 @@ import { BaseWebApi } from "~/src/adaptors/web/base/baseWebApi.ts"
*/
class JianshuWebAdaptor extends BaseWebApi {
public async getMetaData(): Promise<any> {
const res = await this.proxyFetch("https://www.jianshu.com/settings/basic.json")
const notebooks = await this.proxyFetch("https://www.jianshu.com/author/notebooks")
const res = await this.webProxyFetch("https://www.jianshu.com/settings/basic.json")
const avatar = res.data.avatar
const uid = avatar.substring(avatar.lastIndexOf("/") + 1, avatar.lastIndexOf("."))
const flag = !!uid
Expand All @@ -51,7 +54,194 @@ class JianshuWebAdaptor extends BaseWebApi {
supportTypes: ["html"],
home: "https://www.jianshu.com/settings/basic",
icon: "https://www.jianshu.com/favicon.ico",
notebooks: notebooks,
}
}

public async getUsersBlogs(): Promise<Array<UserBlog>> {
let result: UserBlog[] = []
const header = {
accept: "application/json",
}
const notebooks = await this.webProxyFetch("https://www.jianshu.com/author/notebooks", [header])
this.logger.info(`get jianshu notebooks`, notebooks)

if (notebooks && notebooks.length > 0) {
notebooks.forEach((item: any) => {
const useBlog = new UserBlog()

useBlog.blogid = item.id
useBlog.blogName = item.name
result.push(useBlog)
})
}

this.logger.debug("getUsersBlogs=>", result)
return result
}

public async getCategories(): Promise<CategoryInfo[]> {
const cats = [] as CategoryInfo[]

const header = {
accept: "application/json",
}
const notebooks = await this.webProxyFetch("https://www.jianshu.com/author/notebooks", [header])
this.logger.info(`get jianshu notebooks`, notebooks)

if (notebooks && notebooks.length > 0) {
notebooks.forEach((item: any) => {
const cat = new CategoryInfo()
cat.categoryId = item.id
cat.categoryName = item.name
cats.push(cat)
})
}

return cats
}

public async addPost(post: Post) {
this.logger.debug("start add post =>", { post })
// 1 初始化文章,返回文章ID
// 如果没传递过来就用默认的父页面
const notebookId = post.cate_slugs?.[0]?.toString() ?? this.cfg.blogid.toString()
const initHeader = {
accept: "application/json",
}
const initParams = {
notebook_id: notebookId,
title: post.title,
at_bottom: false,
}
const initRes = await this.webProxyFetch("https://www.jianshu.com/author/notes", [initHeader], initParams, "POST")
this.logger.debug("jianshu addPost initRes =>", initRes)
const pageId = initRes.id
const endUrl = initRes.slug

// 文章更新并发布
await this.updateJianshuArticle(pageId, post.title, post.description, 1)
this.logger.info(`文章发布成功,开始组装简书的ID组合,pageId=${pageId},notebookId=${notebookId},endUrl=${endUrl}`)
const postid = [pageId, notebookId, endUrl].join("_")
return {
status: "success",
post_id: postid,
}
}

public async getPreviewUrl(postid: string): Promise<string> {
const purl = this.cfg.previewUrl ?? ""
const jianshuPostKey = this.getJianshuPostidKey(postid)
// const pageId = jianshuPostKey.pageId
const endUrl = jianshuPostKey.endUrl
const postUrl = purl.replace("[postid]", endUrl)
return StrUtil.pathJoin(this.cfg.home ?? "", postUrl)
}

public async deletePost(postid: string): Promise<boolean> {
const jianshuPostKey = this.getJianshuPostidKey(postid)
const pageId = jianshuPostKey.pageId

const header = {
accept: "application/json",
}
const res = await this.webProxyFetch(
`https://www.jianshu.com/author/notes/${pageId}/soft_destroy`,
[header],
undefined,
"POST"
)
this.logger.debug("jianshu delete post res =>", res)

return true
}

public async editPost(postid: string, post: Post, publish?: boolean): Promise<boolean> {
let flag = false
try {
const jianshuPostKey = this.getJianshuPostidKey(postid)
const pageId = jianshuPostKey.pageId

// 文章更新并发布
await this.updateJianshuArticle(pageId, post.title, post.description)
flag = true
} catch (e) {
this.logger.error("简书文章更新失败", e)
}

return flag
}

// ================
// private methods
// ================
/**
* 获取封装的postid
*
* @param postid
* @private postid
*/
private getJianshuPostidKey(postid: string): any {
let pageId: string
let notebookId: string
let endUrl: string
if (postid.indexOf("_") > 0) {
const idArr = postid.split("_")
pageId = idArr[0]
notebookId = idArr[1]
endUrl = idArr[2]
} else {
pageId = postid
}

return {
pageId: pageId,
notebookId: notebookId,
endUrl: endUrl,
}
}

/**
*
* @param pageId - 文章ID
* @param title - 标题
* @param conetnt -正文
* @param autosave_control 版本号码,更新必须增加
* @private
*/
private async updateJianshuArticle(pageId: string, title: string, conetnt: string, autosave_control: number = 1) {
// 1 实时保存文章
const saveHeader = {
accept: "application/json",
}
const saveParams = {
id: pageId,
autosave_control: autosave_control,
title: title,
content: conetnt,
}
const saveRes = await this.webProxyFetch(
`https://www.jianshu.com/author/notes/${pageId}`,
[saveHeader],
saveParams,
"PUT"
)
this.logger.debug("jianshu savePost saveRes =>", saveRes)

// 2 文章发布
try {
const publishHeader = {
accept: "application/json",
}
const pubRes = await this.webProxyFetch(
`https://www.jianshu.com/author/notes/${pageId}/publicize`,
[publishHeader],
{},
"POST"
)
this.logger.debug("jianshu publishPost pubRes =>", pubRes)
} catch (e) {
ElMessage.warning("简书文章发布失败,内容已存入草稿 =>" + e)
this.logger.error("简书文章发布失败", e)
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/adaptors/web/jianshu/useJianshuWeb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { JsonUtil, ObjectUtil, StrUtil } from "zhi-common"
import { Utils } from "~/src/utils/utils.ts"
import { getDynPostidKey } from "~/src/platforms/dynamicConfig.ts"
import { JianshuWebAdaptor } from "~/src/adaptors/web/jianshu/jianshuWebAdaptor.ts"
import {CategoryTypeEnum} from "zhi-blog-api";

/**
* 用于获取JianshuWeb的API的自定义Hook
Expand Down Expand Up @@ -80,8 +81,18 @@ const useJianshuWeb = async (key?: string, newCfg?: JianshuConfig) => {
}
}

cfg.tagEnabled = false
cfg.cateEnabled = false
cfg.knowledgeSpaceEnabled = true
cfg.knowledgeSpaceTitle = "笔记本"
cfg.knowledgeSpaceType = CategoryTypeEnum.CategoryType_Single
cfg.allowKnowledgeSpaceChange = false
cfg.placeholder.knowledgeSpaceReadonlyModeTip =
"由于简书平台的限制,暂时不支持编辑所属笔记本。如果您想移动文档,请先点击取消删除该文档,然后重新选择新的笔记本发布"

const webApi = new JianshuWebAdaptor(appInstance, cfg)
return {
cfg,
webApi,
}
}
Expand Down
Loading

0 comments on commit 3c3e49e

Please sign in to comment.