Molunerfinn / PicGo

:rocket:A simple & beautiful tool for pictures uploading built by vue-cli-electron-builder
https://molunerfinn.com/PicGo/
MIT License
24.24k stars 2.24k forks source link

[Feature]: 插件支持 Oauth 授权方式 #1183

Closed xinatcg closed 1 year ago

xinatcg commented 1 year ago

前置阅读 | Pre-reading

PicGo的版本 | PicGo Version

2.3.0

系统信息 | System Information

Mac

功能请求 | Feature request

https://github.com/PicGo/PicGo-Core/issues/162

我看了开发文档, 好像没有提供这种授权方式, 不知道是不是需要一些 GUI 的支持, 另外也比较困惑是否可行.

按照 Oauth 的流程, 需要首先点击一个按钮, 跳转到网页端,让用户登陆账号并授权, 授权完成后, 会有相应的 token 生成, 使用这个 token 进行 API 调用.

就是插件可以支持

  1. 跳转到网页
  2. 可以保存 credential 到某个目录
Molunerfinn commented 1 year ago

插件可以支持。

xinatcg commented 1 year ago

插件可以支持。

谢谢, 请问有相关文档或者参考? 我看官方的插件文件没有相关内容.

Molunerfinn commented 1 year ago

跳转到网页,保存 credential 到某个目录,都不需要 picgo 提供支持, node 环境下有可以处理的 npm 包

xinatcg commented 1 year ago

跳转到网页,保存 credential 到某个目录,都不需要 picgo 提供支持, node 环境下有可以处理的 npm 包

目前已经实现 oauth 的授权流程和文件上传, 我看到 GUI Plugin 有 command 的功能. 可以注册快捷键触发动作. 我想问一下这个快捷键可以实现触发使用制定的 uploader上传吗.

比如我们的 picgo 配置的默认 图床为 github. 这个配置不更改, 这样默认的快捷键还是触发 github 上传. 我自己的 google drive uploader plugin 注册了新的快捷键, 这个快捷键触发上传, 通过 google drive upload 上传. 这个可以实现吗?

我看到 guiAPi 有个一 upload([file]), 但是好像这个还是使用 picgo 配置的 upload 来上传.

我尝试直接访问 ctx 的 output, 但是快捷键触发后这个数据为空. 或者有办法手动来触发上传的前半部分操作, 就是获取剪切板图片保存到 ctx 中

Molunerfinn commented 1 year ago

可以,调用 upload 之前,可以先调用 setConfig,把 uploader 变成你的图床;然后上传结束后再恢复成原来的 uploader 即可。

你需要实现的是你自己的 uploader,这样才能在 uploader 中的 ctx 上拿到对应的图片信息

xinatcg commented 1 year ago

可以,调用 upload 之前,可以先调用 setConfig,把 uploader 变成你的图床;然后上传结束后再恢复成原来的 uploader 即可。

你需要实现的是你自己的 uploader,这样才能在 uploader 中的 ctx 上拿到对应的图片信息

请问这个具体 API是什么? 是通过 ctx 吗?

这是我目前的插件, 已经实现 uploadProcess(ctx) 已经实现了标准的上传流程.

我想在这个 command 中直接触发当前plugin 的上传.
https://github.com/xinatcg/picgo-plugin-gdrive/blob/794f4221ef76f35a250ffc0385d4c9f36f4b25af/src/index.ts#L265C9-L265C33

我是不是需要在这个方法里面实现你说的那些逻辑?

xinatcg commented 1 year ago

另外还有个小问题. 我想在插件中直接将图片链接 copy 到 clipboard 中. 因为这个插件只能提供 link, markdown 格式 并没什么用途. 所以我想让这个插件只 copy link. 同时全局的配置保持为 markdown 为全局 Github 配置使用. 我尝试了价格 npm 包来 copy, 但是似乎 picgo 不允许, 在执行的时候都报错了, 请问我可以实现这个吗? 还是有其他更好的方法来实现我的需求?

Molunerfinn commented 1 year ago

可以,调用 upload 之前,可以先调用 setConfig,把 uploader 变成你的图床;然后上传结束后再恢复成原来的 uploader 即可。 你需要实现的是你自己的 uploader,这样才能在 uploader 中的 ctx 上拿到对应的图片信息

请问这个具体 API是什么? 是通过 ctx 吗?

这是我目前的插件, 已经实现 uploadProcess(ctx) 已经实现了标准的上传流程.

我想在这个 command 中直接触发当前plugin 的上传. xinatcg/picgo-plugin-gdrive@794f422/src/index.ts#L265C9-L265C33

我是不是需要在这个方法里面实现你说的那些逻辑?

对。getConfig 和 setConfig 是 ctx 暴露的 api :https://picgo.github.io/PicGo-Core-Doc/zh/api/#setconfig-config

伪代码如下:

const originPicBed = ctx.getConfig('picBed.uploader')
ctx.setConfig({ picBed: { uploader: 'xxx' }}) // 替换当前的图床为你的图床名
try {
  await uploadProcess(ctx)
} finally {
  ctx.setConfig({ picBed: { uploader: originPicBed }}) // 还原
}

但是如果直接调用你自己实现的 uploadProcess 的话,图片链接自动拷贝到剪贴板、相册里出现图片等功能都会无效(因为这部分逻辑是封装在 GUI 版本里的);建议切换完图床之后直接使用 guiApi 的 upload 方法。

const originPicBed = ctx.getConfig('picBed.uploader')
ctx.setConfig({ picBed: { uploader: 'xxx' }}) // 替换当前的图床为你的图床名
try {
  await guiApi.upload(xxx)
} finally {
  ctx.setConfig({ picBed: { uploader: originPicBed }}) // 还原
}
Molunerfinn commented 1 year ago

另外还有个小问题. 我想在插件中直接将图片链接 copy 到 clipboard 中. 因为这个插件只能提供 link, markdown 格式 并没什么用途. 所以我想让这个插件只 copy link. 同时全局的配置保持为 markdown 为全局 Github 配置使用. 我尝试了价格 npm 包来 copy, 但是似乎 picgo 不允许, 在执行的时候都报错了, 请问我可以实现这个吗? 还是有其他更好的方法来实现我的需求?

picgo 不限制你使用的 npm 包,报错的话需要你自己看看是什么原因,有可能你用的是 web 上的 clipboard 包而非 node 上的。 node 上的包如:https://www.npmjs.com/package/node-clipboardy

另外如果你要只做拷贝 link,可以先修改 picgo 的拷贝格式:saveConfig({settings: {pasteStyle: 'URL'}}) 然后调用 guiApi 提供的 upload 方法上传图片,这样会自动拷贝图片连接到剪贴板,然后再 saveConfig({settings: {pasteStyle: 'markdown'}}) 就还原成 markdown 格式了。跟切换图床的方法是类似的,区别在于这个值需要落地才能生效,所以需要用 saveConfig 而不是 setConfig

xinatcg commented 1 year ago

可以,调用 upload 之前,可以先调用 setConfig,把 uploader 变成你的图床;然后上传结束后再恢复成原来的 uploader 即可。 你需要实现的是你自己的 uploader,这样才能在 uploader 中的 ctx 上拿到对应的图片信息

请问这个具体 API是什么? 是通过 ctx 吗? 这是我目前的插件, 已经实现 uploadProcess(ctx) 已经实现了标准的上传流程. 我想在这个 command 中直接触发当前plugin 的上传. xinatcg/picgo-plugin-gdrive@794f422/src/index.ts#L265C9-L265C33 我是不是需要在这个方法里面实现你说的那些逻辑?

对。getConfig 和 setConfig 是 ctx 暴露的 api :https://picgo.github.io/PicGo-Core-Doc/zh/api/#setconfig-config

伪代码如下:

const originPicBed = ctx.getConfig('picBed.uploader')
ctx.setConfig({ picBed: { uploader: 'xxx' }}) // 替换当前的图床为你的图床名
try {
  await uploadProcess(ctx)
} finally {
  ctx.setConfig({ picBed: { uploader: originPicBed }}) // 还原
}

但是如果直接调用你自己实现的 uploadProcess 的话,图片链接自动拷贝到剪贴板、相册里出现图片等功能都会无效(因为这部分逻辑是封装在 GUI 版本里的);建议切换完图床之后直接使用 guiApi 的 upload 方法。

const originPicBed = ctx.getConfig('picBed.uploader')
ctx.setConfig({ picBed: { uploader: 'xxx' }}) // 替换当前的图床为你的图床名
try {
  await guiApi.upload(xxx)
} finally {
  ctx.setConfig({ picBed: { uploader: originPicBed }}) // 还原
}

非常感谢, 我测试了一下, 能够触发对应的 uploader 上传. 不过好像 ctx.setConfig 这个 API 好像更新 config 的方式有点出入. 上面的代码会丢失 picBed 下面各个 uploader 对应的配置.

之前的 config

image

之后的 config image

所以这里我们是不是需要首先获取全部的 config, 然后在 修改 current 和 uploader, 在 setConfig, 就是说需要取出全部的 config, 然后更改一部分, 再 set 回去.

xinatcg commented 1 year ago

可以,调用 upload 之前,可以先调用 setConfig,把 uploader 变成你的图床;然后上传结束后再恢复成原来的 uploader 即可。 你需要实现的是你自己的 uploader,这样才能在 uploader 中的 ctx 上拿到对应的图片信息

请问这个具体 API是什么? 是通过 ctx 吗? 这是我目前的插件, 已经实现 uploadProcess(ctx) 已经实现了标准的上传流程. 我想在这个 command 中直接触发当前plugin 的上传. xinatcg/picgo-plugin-gdrive@794f422/src/index.ts#L265C9-L265C33 我是不是需要在这个方法里面实现你说的那些逻辑?

对。getConfig 和 setConfig 是 ctx 暴露的 api :https://picgo.github.io/PicGo-Core-Doc/zh/api/#setconfig-config 伪代码如下:

const originPicBed = ctx.getConfig('picBed.uploader')
ctx.setConfig({ picBed: { uploader: 'xxx' }}) // 替换当前的图床为你的图床名
try {
  await uploadProcess(ctx)
} finally {
  ctx.setConfig({ picBed: { uploader: originPicBed }}) // 还原
}

但是如果直接调用你自己实现的 uploadProcess 的话,图片链接自动拷贝到剪贴板、相册里出现图片等功能都会无效(因为这部分逻辑是封装在 GUI 版本里的);建议切换完图床之后直接使用 guiApi 的 upload 方法。

const originPicBed = ctx.getConfig('picBed.uploader')
ctx.setConfig({ picBed: { uploader: 'xxx' }}) // 替换当前的图床为你的图床名
try {
  await guiApi.upload(xxx)
} finally {
  ctx.setConfig({ picBed: { uploader: originPicBed }}) // 还原
}

非常感谢, 我测试了一下, 能够触发对应的 uploader 上传. 不过好像 ctx.setConfig 这个 API 好像更新 config 的方式有点出入. 上面的代码会丢失 picBed 下面各个 uploader 对应的配置.

之前的 config

image

之后的 config image

所以这里我们是不是需要首先获取全部的 config, 然后在 修改 current 和 uploader, 在 setConfig, 就是说需要取出全部的 config, 然后更改一部分, 再 set 回去.

通过测试, 这种方式工作正常

  1. 获取全部 config
  2. 记录 current 和 uploader, 然后更新这两个
  3. 最后把旧的 set 回去

        const config: any = ctx.getConfig()
        ctx.log.info('>> userConfigBefore')
        ctx.log.info(JSON.stringify(config))

        const originCurrent = config.picBed.current
        const originUploader = config.picBed.uploader

        config.picBed.current = 'Google Drive'
        config.picBed.uploader = 'Google Drive'
        ctx.log.info('>> userConfigBefore')
        ctx.log.info(JSON.stringify(config))
        ctx.log.info('>> updateUserConfigBefore')
        ctx.log.info(JSON.stringify(config))

        // ctx.log.info('>> GDrive >> command trigger >> origin config')

        // ctx.setConfig({ picBed: { uploader: 'Google Drive', 'Google Drive': gdriveConfig } }) // 替换当前的图床为你的图床名

        ctx.setConfig(config)
        try {
          await guiApi.upload()
        } finally {
          ctx.log.info('>> finally')
          config.picBed.current = originCurrent
          config.picBed.uploader = originUploader
          ctx.log.info(JSON.stringify(config))
          ctx.setConfig(config)
          // ctx.setConfig({ picBed: { uploader: originPicBed } }) // 还原
        }
        // await uploadProcess(ctx)
xinatcg commented 1 year ago

现在的 ctx.setConfig , 如果没有提供字段, 可能保留第一级配置, 第二级就会清空.

xinatcg commented 1 year ago

@Molunerfinn 非常感谢帮助, 已经提交 PR 到 https://github.com/PicGo/Awesome-PicGo