Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new version of picgo #329

Merged
merged 67 commits into from Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
44ee923
chore: update deps
terwer Mar 20, 2024
54a136c
chore: support remote picture url
terwer Mar 20, 2024
3539519
chore: support base64
terwer Mar 20, 2024
8668352
chore: support base64
terwer Mar 20, 2024
1b36f70
chore: add file or blob support
terwer Mar 20, 2024
e4867c3
chore: add file or blob support
terwer Mar 20, 2024
26413dc
chore: browser support url upload
terwer Mar 20, 2024
f14765d
chore: browser support request proxy
terwer Mar 20, 2024
e325b93
chore: browser support request proxy
terwer Mar 20, 2024
c825d68
chore: add more pages
terwer Mar 20, 2024
282192e
feat: support some setting
terwer Mar 20, 2024
e2134ad
feat: add siyuan api
terwer Mar 20, 2024
88df15d
feat: add siyuan api
terwer Mar 20, 2024
610be2c
feat: change siyuan api default config path
terwer Mar 20, 2024
3300b44
feat: change siyuan api default config path
terwer Mar 20, 2024
95ebc61
feat: init siyuan picgo
terwer Mar 21, 2024
af4a2f1
feat: config update
terwer Mar 21, 2024
0b930c8
feat: update siyuan setting
terwer Mar 21, 2024
6aed459
feat: support external picgo
terwer Mar 21, 2024
3cd4047
feat: add post api
terwer Mar 21, 2024
0f32994
feat: add post api
terwer Mar 21, 2024
5a673df
feat: add post api
terwer Mar 21, 2024
ca52410
feat: external picgo setting
terwer Mar 21, 2024
49a0ed4
feat: bundled picgo setting
terwer Mar 21, 2024
aa068bb
fix: import error
terwer Mar 21, 2024
f105b1d
fix: import error
terwer Mar 21, 2024
ee955b0
feat: upload list
terwer Mar 21, 2024
8482c3a
feat: browser upload list
terwer Mar 21, 2024
aeb9c1b
feat: pic bed config
terwer Mar 22, 2024
7e4dc05
feat: update pic bed config
terwer Mar 22, 2024
76996ec
feat: update pic bed config
terwer Mar 22, 2024
7eeae05
feat: update pic bed config
terwer Mar 22, 2024
a4aaae1
feat: update picgo config
terwer Mar 22, 2024
025d5f6
feat: reactive config setting
terwer Mar 22, 2024
9e15e43
feat: reactive config setting
terwer Mar 22, 2024
616d73f
fix: config init should before request
terwer Mar 23, 2024
1043cb2
feat: update config
terwer Mar 23, 2024
b0af419
feat: picbed config
terwer Mar 25, 2024
3a5560f
feat: picbed config
terwer Mar 25, 2024
9af22a6
feat: picbed config
terwer Mar 25, 2024
b3a9b5e
feat: loding style
terwer Mar 25, 2024
b7a1d48
feat: support gitlab
terwer Mar 25, 2024
7b24e50
feat: support gitlab upload
terwer Mar 25, 2024
db08307
feat: gitlab no need proxy
terwer Mar 25, 2024
3355f03
feat: remove default encode behavior
terwer Mar 25, 2024
54712f8
feat: remove token for public projects
terwer Mar 25, 2024
83bfbfa
feat: remove token for public projects
terwer Mar 25, 2024
3b28338
feat: add image download support
terwer Mar 25, 2024
86fc400
feat: support drag upload
terwer Mar 25, 2024
89adcb8
feat: support drag upload
terwer Mar 25, 2024
218f32c
feat: new method for extract file name
terwer Mar 26, 2024
3e241e0
feat: avoid refresh page after upload
terwer Mar 26, 2024
9b8ca99
feat: allow image copy for different types
terwer Mar 26, 2024
853fe48
feat: allow image copy for different types
terwer Mar 26, 2024
e453bf1
feat: allow image copy for different types
terwer Mar 26, 2024
1847889
feat: allow image copy for different types
terwer Mar 26, 2024
e6dc381
feat: support github
terwer Mar 26, 2024
32ace45
feat: support aliyun via cors proxy
terwer Mar 26, 2024
5e09220
feat: support aliyun
terwer Mar 26, 2024
80df23e
feat: support imgur
terwer Mar 26, 2024
3cb223a
feat: support qiniu
terwer Mar 26, 2024
ada39eb
feat: support qiniu without proxy
terwer Mar 26, 2024
ea1798d
feat: upyun todo
terwer Mar 26, 2024
b4fc844
feat: support tencent cos
terwer Mar 27, 2024
3ea89d8
feat: support upyun
terwer Mar 27, 2024
c5d90da
chore: prepare for release
terwer Mar 27, 2024
ab9f909
chore: new version of picgo picbed
terwer Mar 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -4,7 +4,7 @@

![](./preview.png)

Your favorite PicGo image bed and PicGo plugins are still available in siyuan-notes, wuhu~
Your favorite PicGo image bed is still available in siyuan-notes, wuhu~

> Important Note:
>
Expand Down
2 changes: 1 addition & 1 deletion README_zh_CN.md
Expand Up @@ -4,7 +4,7 @@

![](./preview.png)

您喜爱的 PicGo 图床与 PicGo 插件,在思源笔记依然可用,没想到吧~
您喜爱的 PicGo 图床在思源笔记依然可用,没想到吧~

> 重要提示:
>
Expand Down
Binary file modified icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icon.psd
Binary file not shown.
6 changes: 5 additions & 1 deletion libs/Universal-PicGo-Core/custom.d.ts
@@ -1,4 +1,8 @@
declare module '*.json' {
const value: { [key: string]: any }
export default value
}
}

declare module "ali-oss"
declare module "arraybuffer-to-buffer"
declare module "upyun"
3 changes: 3 additions & 0 deletions libs/Universal-PicGo-Core/package.json
Expand Up @@ -27,13 +27,16 @@
"devDependencies": {
"@terwer/eslint-config-custom": "^1.3.6",
"@terwer/vite-config-custom": "^0.7.6",
"@types/mime-types": "^2.1.4",
"vite-plugin-node-polyfills": "^0.21.0"
},
"dependencies": {
"@picgo/i18n": "^1.0.0",
"ali-oss": "^6.20.0",
"axios": "^1.6.8",
"dayjs": "^1.11.10",
"js-yaml": "^4.1.0",
"mime-types": "^2.1.35",
"queue": "^7.0.0",
"universal-picgo-store": "workspace:*",
"zhi-lib-base": "^0.8.0"
Expand Down
122 changes: 122 additions & 0 deletions libs/Universal-PicGo-Core/src/core/ExternalPicgo.ts
@@ -0,0 +1,122 @@
/*
* GNU GENERAL PUBLIC LICENSE
* Version 3, 29 June 2007
*
* Copyright (C) 2022-2024 Terwer, Inc. <https://terwer.space/>
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/

import { ILogger, simpleLogger } from "zhi-lib-base"
import ExternalPicgoConfigDb from "../db/externalPicGo"
import { IImgInfo, IPicGo } from "../types"
import { PicgoTypeEnum } from "../utils/enums"
import { browserPathJoin } from "../utils/browserUtils"
import { isFileOrBlob } from "../utils/common"

/**
*外部的PicGO 上传 Api
*
* @since 0.6.0
* @version 1.6.0
* @author terwer
*/
class ExternalPicgo {
private logger: ILogger
private requestUrl = "http://127.0.0.1:36677"
private readonly endpointUrl = "/upload"
public db: ExternalPicgoConfigDb

constructor(ctx: IPicGo, isDev?: boolean) {
this.logger = simpleLogger("external-picgo", "external-picgo", isDev)
this.db = new ExternalPicgoConfigDb(ctx)
}

/**
* 上传图片到PicGO
*
* @param input 路径数组,可为空,为空上传剪贴板
*/
public async upload(input?: any[]): Promise<IImgInfo[] | Error> {
const useBundledPicgo = this.db.get("useBundledPicgo")
const picgoType = this.db.get("picgoType")
if (useBundledPicgo) {
throw new Error("bundled picgo cannot use extenal picgo api")
}
if (picgoType !== PicgoTypeEnum.App) {
throw new Error(`picgoType ${picgoType} is not supported via external picgo api`)
}

// check blob
let hasBlob = false
if (input) {
for (const inputItem of input) {
if (isFileOrBlob(inputItem) || typeof inputItem !== "string") {
hasBlob = true
break
}
}
}
if (hasBlob) {
throw new Error("blob is not supported via external picgo api")
}

this.requestUrl = this.db.get("extPicgoApiUrl") ?? this.requestUrl
let ret: IImgInfo[] = []

const fetchOptions = {
method: "POST",
}

let data
// 传递了路径,上传具体图片,否则上传剪贴板
if (input) {
data = { list: input }
}

// 数据不为空才传递
if (data) {
Object.assign(fetchOptions, {
body: JSON.stringify(data),
})
}

Object.assign(fetchOptions, {
headers: {
"Content-Type": "application/json",
"User-Agent": "Terwer/0.1.0",
},
})

// 发送请求
const apiUrl = browserPathJoin(this.requestUrl, this.endpointUrl)
this.logger.debug("调用HTTP请求上传图片到PicGO,apiUrl=>", apiUrl)
this.logger.debug("调用HTTP请求上传图片到PicGO,fetchOps=>", fetchOptions)

// 使用兼容的fetch调用并返回统一的JSON数据
const response = await fetch(apiUrl, fetchOptions)
const resJson = await response.json()
this.logger.debug("调用HTTP请求上传图片到PicGO,resJson=>", resJson)

if (resJson.success) {
const rtnArray: IImgInfo[] = []
if (resJson.result && resJson.result.length > 0) {
resJson.result.forEach((img: string) => {
const rtnItem = {
fileName: img.substring(img.lastIndexOf("/") + 1),
imgUrl: img,
}
rtnArray.push(rtnItem)
})
}

ret = rtnArray
} else {
throw new Error("调用HTTP上传到PicGO失败,请检查配置=>" + resJson.message)
}

return Promise.resolve(ret)
}
}

export { ExternalPicgo }
6 changes: 2 additions & 4 deletions libs/Universal-PicGo-Core/src/core/Lifecycle.ts
Expand Up @@ -12,7 +12,6 @@ import { ILifecyclePlugins, IPicGo, IPlugin, Undefinable } from "../types"
import { ILogger } from "zhi-lib-base"
import { createContext } from "../utils/createContext"
import { IBuildInEvent } from "../utils/enums"
import { handleUrlEncode } from "../utils/common"

export class Lifecycle extends EventEmitter {
private readonly ctx: IPicGo
Expand Down Expand Up @@ -114,11 +113,9 @@ export class Lifecycle extends EventEmitter {
await this.handlePlugins(ctx.helper.afterUploadPlugins, ctx)
let msg = ""
const length = ctx.output.length
// notice, now picgo builtin uploader will encodeOutputURL by default
const isEncodeOutputURL = ctx.getConfig<Undefinable<boolean>>("settings.encodeOutputURL") === true
for (let i = 0; i < length; i++) {
if (typeof ctx.output[i].imgUrl !== "undefined") {
msg += isEncodeOutputURL ? handleUrlEncode(ctx.output[i].imgUrl!) : ctx.output[i].imgUrl!
msg += ctx.output[i].imgUrl!
if (i !== length - 1) {
msg += "\n"
}
Expand All @@ -129,6 +126,7 @@ export class Lifecycle extends EventEmitter {
ctx.emit(IBuildInEvent.FINISHED, ctx)
if (msg === "") {
ctx.log.warn("[after-upload] image upload occured an error, please read log for details")
throw new Error("image upload occured an error, please read log for details")
} else {
ctx.log.info(`[after-upload] upload finishied => \n${msg}`)
}
Expand Down
83 changes: 47 additions & 36 deletions libs/Universal-PicGo-Core/src/core/UniversalPicGo.ts
Expand Up @@ -17,7 +17,6 @@ import {
IPicGo,
IPicGoPlugin,
IPicGoPluginInterface,
IPicGoRequest,
IPluginLoader,
IStringKeyMap,
} from "../types"
Expand All @@ -32,7 +31,7 @@ import getClipboardImage from "../utils/getClipboardImage"
import { IBuildInEvent, IBusEvent } from "../utils/enums"
import ConfigDb from "../db/config"
import { hasNodeEnv, win } from "universal-picgo-store"
import { ensureFileSync, pathExistsSync } from "../utils/nodeUtils"
import { ensureFileSync, ensureFolderSync, pathExistsSync } from "../utils/nodeUtils"
import { I18nManager } from "../i18n"
import { browserPathJoin, getBrowserDirectoryPath } from "../utils/browserUtils"
import { isConfigKeyInBlackList, isInputConfigValid } from "../utils/common"
Expand All @@ -52,9 +51,9 @@ class UniversalPicGo extends EventEmitter implements IPicGo {
private _pluginLoader!: PluginLoader
configPath: string
baseDir!: string
pluginBaseDir!: string
helper!: IHelper
log: ILogger
// cmd: Commander
output: IImgInfo[]
input: any[]
pluginHandler: PluginHandler
Expand All @@ -63,8 +62,6 @@ class UniversalPicGo extends EventEmitter implements IPicGo {
VERSION: string = process.env.PICGO_VERSION ?? "unknown"
private readonly isDev: boolean

// GUI_VERSION?: string

get pluginLoader(): IPluginLoader {
return this._pluginLoader
}
Expand All @@ -77,11 +74,12 @@ class UniversalPicGo extends EventEmitter implements IPicGo {
return this.requestWrapper.PicGoRequest.bind(this.requestWrapper)
}

constructor(configPath = "", isDev?: boolean) {
constructor(configPath?: string, pluginBaseDir?: string, isDev?: boolean) {
super()
this.isDev = isDev ?? false
this.log = this.getLogger()
this.configPath = configPath
this.configPath = configPath ?? ""
this.pluginBaseDir = pluginBaseDir ?? ""
this.output = []
this.input = []
this.helper = {
Expand All @@ -92,10 +90,9 @@ class UniversalPicGo extends EventEmitter implements IPicGo {
afterUploadPlugins: new LifecyclePlugins("afterUploadPlugins"),
}
this.initConfigPath()
// this.cmd = new Commander(this)
this.initConfig()
this.pluginHandler = new PluginHandler(this)
this.requestWrapper = new PicGoRequestWrapper(this)
this.initConfig()
this.init()

this.log.info("UniversalPicGo inited")
Expand All @@ -116,18 +113,11 @@ class UniversalPicGo extends EventEmitter implements IPicGo {
}
}

// registerCommands(): void {
// if (this.configPath !== "") {
// this.cmd.init()
// this.cmd.loadCommands()
// }
// }

getConfig<T>(name?: string): T {
getConfig<T>(name?: string, defaultValue?: any): T {
if (!name) {
return this._config as unknown as T
} else {
return _.get(this._config, name)
return _.get(this._config, name, defaultValue)
}
}

Expand Down Expand Up @@ -227,35 +217,56 @@ class UniversalPicGo extends EventEmitter implements IPicGo {

// ===================================================================================================================

private initConfigPath(): void {
this.log.debug("win =>", win)
this.log.info(`hasNodeEnv => ${hasNodeEnv}`)
private getDefautBaseDir(): string {
if (hasNodeEnv) {
const os = win.require("os")
const fs = win.fs
const path = win.require("path")
const { homedir } = os
if (this.configPath === "") {
this.configPath = homedir() + "/.universal-picgo/config.json"
}
if (path.extname(this.configPath).toUpperCase() !== ".JSON") {
this.configPath = ""
throw Error("The configuration file only supports JSON format.")
}
this.baseDir = path.dirname(this.configPath)
const exist = pathExistsSync(fs, path, this.configPath)
if (!exist) {
ensureFileSync(fs, path, `${this.configPath}`)
const dir = path.join(homedir(), ".universal-picgo")
ensureFolderSync(fs, dir)
return dir
} else {
return "universal-picgo"
}
}

private initConfigPath(): void {
if (this.configPath === "") {
this.baseDir = this.getDefautBaseDir()
if (hasNodeEnv) {
const path = win.require("path")
this.configPath = path.join(this.baseDir, "picgo.cfg.json")
} else {
this.configPath = browserPathJoin(this.baseDir, "picgo.cfg.json")
}
} else {
if (this.configPath === "") {
this.baseDir = "universal-picgo"
this.configPath = browserPathJoin(this.baseDir, "config.json")
if (hasNodeEnv) {
const fs = win.fs
const path = win.require("path")

if (path.extname(this.configPath).toUpperCase() !== ".JSON") {
this.configPath = ""
throw Error("The configuration file only supports JSON format.")
}
this.baseDir = path.dirname(this.configPath)
const exist = pathExistsSync(fs, path, this.configPath)
if (!exist) {
ensureFileSync(fs, path, `${this.configPath}`)
}
} else {
// 模拟 path.dirname 的功能,获取路径的目录部分赋值给 baseDir
this.baseDir = getBrowserDirectoryPath(this.configPath)
}
}

if (this.pluginBaseDir === "") {
this.pluginBaseDir = this.getDefautBaseDir()
}

this.log.debug("win =>", win)
this.log.info(`hasNodeEnv => ${hasNodeEnv}`)
this.log.info(`this.baseDir => ${this.baseDir}`)
this.log.info(`this.pluginBaseDir => ${this.pluginBaseDir}`)
}

private initConfig(): void {
Expand Down