diff --git a/src/adaptors/web/bilibili/bilibiliMdUtil.ts b/src/adaptors/web/bilibili/bilibiliMdUtil.ts index 78efee9b..1e63adea 100644 --- a/src/adaptors/web/bilibili/bilibiliMdUtil.ts +++ b/src/adaptors/web/bilibili/bilibiliMdUtil.ts @@ -43,8 +43,8 @@ interface ContentNode { words: string font_size: number font_level: string - style: { - bold: boolean + style?: { + bold?: boolean } } } @@ -121,7 +121,7 @@ class BilibiliMdUtil { * 处理标题节点 */ private static processHeadingNode(node: Node, ops: Op[], paragraphs: Paragraph[]): void { - const level = Math.min(node.HeadingLevel || 2, 2) // 确保最大级别为 2 + const level = Math.min(node.HeadingLevel || 2, 2) const text = node.Children?.map((child) => (child.Type === "NodeText" ? child.Data || "" : "")).join("") || "" // 添加标题文本到 ops @@ -130,15 +130,15 @@ class BilibiliMdUtil { // 将标题转换为 content const paragraph: Paragraph = { - para_type: 2, // 假设标题类型为 2 + para_type: 1, text: { nodes: [ { - node_type: 1, // 假设文本节点 + node_type: 1, word: { words: text, - font_size: 22, - font_level: "xLarge", + font_size: level > 1 ? 22 : 24, + font_level: level > 1 ? "xLarge" : "xxLarge", style: { bold: true }, }, }, @@ -173,15 +173,15 @@ class BilibiliMdUtil { // 将列表项转换为 content const paragraph: Paragraph = { - para_type: 3, // 假设列表项类型为 3 + para_type: 1, text: { nodes: [ { node_type: 1, word: { words: text, - font_size: 22, - font_level: "xLarge", + font_size: 24, + font_level: "xxLarge", style: { bold: true }, }, }, @@ -200,16 +200,16 @@ class BilibiliMdUtil { // 将段落转换为 content const paragraph: Paragraph = { - para_type: 1, // 假设类型为 1 + para_type: 1, text: { nodes: [ { node_type: 1, word: { words: text, - font_size: 22, - font_level: "xLarge", - style: { bold: true }, + font_size: 17, + font_level: "regular", + style: {}, }, }, ], @@ -227,16 +227,16 @@ class BilibiliMdUtil { // 处理文本内容转化为 content(如果有样式需要调整可修改) const paragraph: Paragraph = { - para_type: 1, // 假设类型为 1 + para_type: 1, text: { nodes: [ { - node_type: 1, // 假设文本节点 + node_type: 1, word: { words: text, - font_size: 22, - font_level: "xLarge", - style: { bold: true }, // 可以根据需求调整 + font_size: 17, + font_level: "regular", + style: {}, }, }, ], diff --git a/src/adaptors/web/bilibili/bilibiliWebAdaptor.ts b/src/adaptors/web/bilibili/bilibiliWebAdaptor.ts index a50224ac..0a00a02f 100644 --- a/src/adaptors/web/bilibili/bilibiliWebAdaptor.ts +++ b/src/adaptors/web/bilibili/bilibiliWebAdaptor.ts @@ -29,8 +29,9 @@ import { BrowserUtil } from "zhi-device" import CookieUtils from "~/src/utils/cookieUtils.ts" import { BilibiliUtils } from "~/src/adaptors/web/bilibili/bilibiliUtils.ts" import { IPublishCfg } from "~/src/types/IPublishCfg.ts" -import { StrUtil } from "zhi-common" +import { JsonUtil, StrUtil } from "zhi-common" import { MockBrowser } from "~/src/utils/MockBrowser.ts" +import WebUtils from "~/src/adaptors/web/base/webUtils.ts" class BilibiliWebAdaptor extends BaseWebApi { private bilibiliMetaDataCfg = {} as any @@ -70,67 +71,67 @@ class BilibiliWebAdaptor extends BaseWebApi { this.logger.debug("bilibili before parse, md=>", post.markdown) const parsedBilibiliContent = BilibiliUtils.parseMd(post.markdown) this.logger.debug("bilibili add post blibiliDatas=>", parsedBilibiliContent) - // const params = JSON.stringify({ - // raw_content: JSON.stringify(parsedBilibiliContent.ops), - // opus_req: { - // // upload_id: "19450592_1734338507_5421", - // upload_id: upload_id, - // opus: { - // opus_source: 2, - // title: post.title, - // content: parsedBilibiliContent.content, - // article: { - // category_id: 15, - // list_id: 0, - // originality: 0, - // reproduced: 0, - // biz_tags: [], - // }, - // pub_info: {}, - // }, - // scene: 12, - // meta: { - // app_meta: { - // from: "create.article.web", - // mobi_app: "web", - // }, - // }, - // option: { - // private_pub: 2, - // }, - // }, - // }) const params = JSON.stringify({ - raw_content: '{"ops":[{"insert":"测试5"},{"attributes":{"header":1},"insert":"\\n"}]}', + raw_content: JSON.stringify(parsedBilibiliContent.ops), opus_req: { - upload_id: "19450592_1734423520_2057", + // upload_id: "19450592_1734338507_5421", + upload_id: upload_id, opus: { opus_source: 2, - title: "测试文章5", - content: { - paragraphs: [ - { - para_type: 1, - text: { - nodes: [ - { - node_type: 1, - word: { words: "测试5", font_size: 24, font_level: "xxLarge", style: { bold: true } }, - }, - ], - }, - }, - ], + title: post.title, + content: parsedBilibiliContent.content, + article: { + category_id: 15, + list_id: 0, + originality: 0, + reproduced: 0, + biz_tags: [], }, - article: { category_id: 15, list_id: 0, originality: 0, reproduced: 0, biz_tags: [] }, pub_info: {}, }, scene: 12, - meta: { app_meta: { from: "create.article.web", mobi_app: "web" } }, - option: { private_pub: 2 }, + meta: { + app_meta: { + from: "create.article.web", + mobi_app: "web", + }, + }, + option: { + private_pub: 2, + }, }, }) // const params = JSON.stringify({ + // raw_content: '{"ops":[{"insert":"测试5"},{"attributes":{"header":1},"insert":"\\n"}]}', + // opus_req: { + // upload_id: "19450592_1734423520_2057", + // opus: { + // opus_source: 2, + // title: "测试文章5", + // content: { + // paragraphs: [ + // { + // para_type: 1, + // text: { + // nodes: [ + // { + // node_type: 1, + // word: { words: "测试5", font_size: 24, font_level: "xxLarge", style: { bold: true } }, + // }, + // ], + // }, + // }, + // ], + // }, + // article: { category_id: 15, list_id: 0, originality: 0, reproduced: 0, biz_tags: [] }, + // pub_info: {}, + // }, + // scene: 12, + // meta: { app_meta: { from: "create.article.web", mobi_app: "web" } }, + // option: { private_pub: 2 }, + // }, + // }) + // const params = JSON.stringify({ // raw_content: '{"ops":[{"insert":"标题1"},{"attributes":{"header":2},"insert":"\\n"}]}', // opus_req: { // upload_id: "19450592_1734413984_9734", @@ -194,13 +195,95 @@ class BilibiliWebAdaptor extends BaseWebApi { } } - public async updatePost(post: Post) { - throw new Error("编辑文章开发中") + public async editPost(postid: string, post: Post, publish?: boolean): Promise { + const userId = this.bilibiliMetaDataCfg.metadata.uid + const upload_id = BilibiliUtils.genUploadId(userId) + // 适配 B 站专门格式 + this.logger.debug("bilibili before parse, md=>", post.markdown) + const parsedBilibiliContent = BilibiliUtils.parseMd(post.markdown) + this.logger.debug("bilibili add post blibiliDatas=>", parsedBilibiliContent) + const params = JSON.stringify({ + raw_content: JSON.stringify({ + ops: parsedBilibiliContent.ops, + }), + opus_req: { + upload_id: upload_id, + opus: { + opus_source: 2, + title: post.title, + content: parsedBilibiliContent.content, + article: { + category_id: 15, + list_id: 0, + originality: 0, + reproduced: 0, + biz_tags: [], + }, + pub_info: {}, + }, + scene: 12, + meta: { app_meta: { from: "create.article.web", mobi_app: "web" } }, + option: {}, + }, + dyn_id_str: this.getDynId(postid), + }) + this.logger.debug("bilibili after parse, params=>", params) + const res = await this.bilibiliFetch( + "/x/dynamic/feed/edit/opus", + {}, + params, + "POST", + "application/json", + false, + true + ) + this.logger.debug("bilibili edit post res=>", res) + if (res?.code !== 0) { + throw new Error(`哔哩哔哩文章更新失败,可能原因:${res?.code} ${res?.message}`) + } + return true + } + + public async deletePost(postid: string): Promise { + const postMeta = this.getPostMeta(postid) + const params = JSON.stringify({ + dyn_id_str: postMeta.dyn_id_str, + dyn_type: postMeta.dyn_type, + rid_str: postMeta.dyn_rid.toString(), + }) + const res = await this.bilibiliFetch( + "/x/dynamic/feed/operate/remove", + {}, + params, + "POST", + "application/json", + false, + true + ) + this.logger.debug("bilibili delete post res=>", res) + if (res?.code !== 0) { + throw new Error(`哔哩哔哩文章删除失败,可能原因:${res?.code} ${res?.message}`) + } + return true + } + + public async getPreviewUrl(postid: string): Promise { + const dynId = this.getDynId(postid) + const previewUrl = this.cfg.previewUrl.replace(/\[postid]/g, dynId) + return previewUrl } // ================ // private methods // ================ + private getDynId(postid: string) { + const postMeta = this.getPostMeta(postid) + return postMeta?.dyn_id_str + } + + private getPostMeta(postid: string) { + return JsonUtil.safeParse(postid, {} as any) + } private async bilibiliFetch( url: string,