此次代码修复是直接修复插件目录下的 main.js,而不是在插件的ts源码中修复后编译

一、发布文章时内容中的本地图片没有被成功上传

只要你文章中引用的本地图片没有放在Obsidian仓库的根目录下,即使在插件设置中打开了 替换媒体链接,图片也无法成功上传至博客中。

其原因是插件在取文件名称时,没有对路径进行剥离(也许插件作者所有图片都在根目录?又或者是作者自己压根不用Obsidian和自己的插件)

修复位置在 updatePostImages 方法中的上半部分。

以下为原始代码:

  async updatePostImages(params) {
    var _a;
    const { postParams, auth } = params;
    const activeFile = this.plugin.app.workspace.getActiveFile();
    if (activeFile === null) {
      throw new Error(this.plugin.i18n.t("error_noActiveFile"));
    }
    const { activeEditor } = this.plugin.app.workspace;
    if (activeEditor && activeEditor.editor) {
      const images = getImages(postParams.content);
      for (const img of images) {
        if (!img.srcIsUrl) {
          const splitFile = img.src.split(".");
          const ext = splitFile.pop();
          const fileName = splitFile.join(".");
          let filePath = await this.plugin.app.vault.getAvailablePathForAttachments(
            fileName,
            ext,
            activeFile
          );
          const pathRegex = /(.*) \d+\.(.*)/;
          filePath = filePath.replace(pathRegex, "$1.$2");
          const imgFile = this.plugin.app.vault.getAbstractFileByPath(filePath);

以下为修复后的代码:

  async updatePostImages(params) {
    var _a;
    const { postParams, auth } = params;
    const activeFile = this.plugin.app.workspace.getActiveFile();
    if (activeFile === null) {
      throw new Error(this.plugin.i18n.t("error_noActiveFile"));
    }
    const { activeEditor } = this.plugin.app.workspace;
    if (activeEditor && activeEditor.editor) {
      const images = getImages(postParams.content);
      for (const img of images) {
        if (!img.srcIsUrl) {
          const splitFile = img.src.split(".");
          const ext = splitFile.pop();
          // const fileName = splitFile.join(".");
          // 这里如果不是在根路径,原本的fileName取出来还带着整个相对路径,因此需要取最后的真正filename
          const fileName = splitFile.pop().split("/").pop();
          let filePath = await this.plugin.app.vault.getAvailablePathForAttachments(
            fileName,
            ext,
            activeFile
          );
          const pathRegex = /(.*) \d+\.(.*)/;
          filePath = filePath.replace(pathRegex, "$1.$2");
          const imgFile = this.plugin.app.vault.getAbstractFileByPath(filePath);

二、发布过的文章,修改后再次发布时又发布为新文章

曾发布过的文章,修改后再次发布时,文章头部的 文档属性 会被清除,导致缺失了 postId 后,被当做新文章直接发布到博客中,而不是更新原有的文章。

导致BUG的原因是插件在上传本地图片后,修改文章中的本地图片路径为网络链接后,使用 activeEditor.editor.setValue方法修改了编辑器中的内容,而这部分内容是不包含原始文章中头部的 文档属性 的,自此文章丢失了文档属性。而插件后续虽然会尝试再次写入文档属性数据,但由于Obsidian自身机制的原因,编辑器中的内容会后续被保存到本地文件中,致使插件后续写入的文档属性失效。

修复位置依然在 updatePostImages 方法中,而这次是下半部分。

以下为原始代码:

            if (result.code === 0 /* OK */) {
              postParams.content = postParams.content.replace(img.original, `![${imgFile.name}](${result.data.url})`);
            } else {
              if (result.error.code === 2 /* ServerInternalError */) {
                new import_obsidian8.Notice(result.error.message, ERROR_NOTICE_TIMEOUT);
              } else {
                new import_obsidian8.Notice(this.plugin.i18n.t("error_mediaUploadFailed", {
                  name: imgFile.name
                }), ERROR_NOTICE_TIMEOUT);
              }
            }
          }
        } else {
        }
      }
      if (this.plugin.settings.replaceMediaLinks) {
        activeEditor.editor.setValue(postParams.content);
      }
    }
  }

以下为修复后的代码:

            if (result.code === 0 /* OK */) {
              postParams.content = postParams.content.replace(img.original, `![${imgFile.name}](${result.data.url})`);
            } else {
              if (result.error.code === 2 /* ServerInternalError */) {
                new import_obsidian8.Notice(result.error.message, ERROR_NOTICE_TIMEOUT);
              } else {
                new import_obsidian8.Notice(this.plugin.i18n.t("error_mediaUploadFailed", {
                  name: imgFile.name
                }), ERROR_NOTICE_TIMEOUT);
              }
            }
          }
        } else {
        }
      }
      if (this.plugin.settings.replaceMediaLinks) {
        // activeEditor.editor.setValue(postParams.content);
        // 这里取原始的MatterData格式化为字符串加到文件内容前面,以保证MatterData不会被清除
        let matterDataString = null;
        const activeFile = this.plugin.app.workspace.getActiveFile();
        if (activeFile) {
          let thiz = this
          await this.plugin.app.fileManager.processFrontMatter(activeFile, (fm) => {
            if (fm) {
              matterDataString = thiz.matterDataFormatString(fm);
            }
          });
        }

        let finalContent = postParams.content;
        if (matterDataString) {
          finalContent = matterDataString + '\n' + finalContent;
        }
        activeEditor.editor.setValue(finalContent);
        // 保存到文件,否则后续processFrontMatter拿不到准确数据
        const file = this.plugin.app.workspace.getActiveFile();
        if (file) {
          await app.vault.modify(file, finalContent);
        }
      }
    }
  }

其中,matterDataFormatString 方法的实现如下,放在与 updatePostImages 方法同级即可:

  matterDataFormatString(md) {
    let result = '---\n';

    if (md.profileName) {
      result += 'profileName: ' + md.profileName + '\n';
    }
    if (md.postId) {
      result += 'postId: \"' + md.postId + '\"\n';
    }
    if (md.postType) {
      result += 'postType: ' + md.postType + '\n';
    }
    if (md.categories) {
      result += 'categories:\n'
      for (let index = 0; index < md.categories.length; index++) {
        result += '  - ' + md.categories[index] + '\n';
      }
    }
    for (let key in md) {
      if (md.hasOwnProperty(key)
        && key != 'profileName'
        && key != 'postId'
        && key != 'postType'
        && key != 'categories') {
        result += key + ': ' + md[key] + '\n';
      }
    }
    result += '---';
    return result;
  }
最后更新于 2024-03-22