Skip to content

Commit

Permalink
feat: #21 support lsky pro 2.1+
Browse files Browse the repository at this point in the history
  • Loading branch information
terwer committed Jun 4, 2024
1 parent 959b697 commit c26415f
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ yarn-error.log*
artifacts
cookie.txt
token.txt
__pycache__
__pycache__
.typora
10 changes: 10 additions & 0 deletions libs/Universal-PicGo-Core/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ export const EN: ILocales = {
PICBED_AWSS3PLIST_MESSAGE_ACL: "Ex. public-read",
PICBED_AWSS3PLIST_MESSAGE_CORS_PROXY: "Enable when suffering from CORS issue",

PICBED_LSKY: "Lsky Pro",
PICBED_ISKY_SERVER: "Api url",
PICBED_ISKY_MESSAGE_SERVER: "Example: http://localhost:9080",
PICBED_ISKY_EMAIL: "Email",
PICBED_ISKY_MESSAGE_EMAIL: "Email",
PICBED_ISKY_PASSWORD: "Password",
PICBED_ISKY_MESSAGE_PASSWORD: "Password",
PICBED_ISKY_STRATEGYID: "Policy ID",
PICBED_ISKY_MESSAGE_STRATEGYID: "Optional, please leave blank when using default storage policy",

// Plugin Handler
PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS: "Plugin installed successfully",
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED: "Plugin installation failed",
Expand Down
10 changes: 10 additions & 0 deletions libs/Universal-PicGo-Core/src/i18n/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,16 @@ export const ZH_CN = {
PICBED_AWSS3PLIST_MESSAGE_ACL: "例如:public-read",
PICBED_AWSS3PLIST_MESSAGE_CORS_PROXY: "需要时启用",

PICBED_LSKY: "兰空图床",
PICBED_ISKY_SERVER: "API 地址",
PICBED_ISKY_MESSAGE_SERVER: "示例: http://localhost:9080",
PICBED_ISKY_EMAIL: "邮箱",
PICBED_ISKY_MESSAGE_EMAIL: "邮箱,用于生成鉴权 token",
PICBED_ISKY_PASSWORD: "密码",
PICBED_ISKY_MESSAGE_PASSWORD: "密码,用于生成鉴权 token",
PICBED_ISKY_STRATEGYID: "策略 ID",
PICBED_ISKY_MESSAGE_STRATEGYID: "选填, 使用默认存储策略时请留空",

// Plugin Handler
PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS: "插件安装成功",
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED: "插件安装失败",
Expand Down
10 changes: 10 additions & 0 deletions libs/Universal-PicGo-Core/src/i18n/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ export const ZH_TW: ILocales = {
PICBED_AWSS3PLIST_MESSAGE_ACL: "例如:public-read",
PICBED_AWSS3PLIST_MESSAGE_CORS_PROXY: "需要時啟用",

PICBED_LSKY: "蘭空圖床",
PICBED_ISKY_SERVER: "API 地址",
PICBED_ISKY_MESSAGE_SERVER: "示例: http://localhost:9080",
PICBED_ISKY_EMAIL: "郵箱",
PICBED_ISKY_MESSAGE_EMAIL: "郵箱,用於生成鑒權 token",
PICBED_ISKY_PASSWORD: "密碼",
PICBED_ISKY_MESSAGE_PASSWORD: "密碼,用於生成鑒權 token",
PICBED_ISKY_STRATEGYID: "策略 ID",
PICBED_ISKY_MESSAGE_STRATEGYID: "選填, 使用默認存儲策略時請留空",

// Plugin Handler
PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS: "插件安裝成功",
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED: "插件安裝失敗",
Expand Down
2 changes: 2 additions & 0 deletions libs/Universal-PicGo-Core/src/plugins/uploader/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import upyunUploader from "./upyun"
import SMMSUploader from "./smms"
import imgurUploader from "./imgur"
import awss3Uploader from "./awss3"
import lskyUploader from "./lsky"

const buildInUploaders: IPicGoPlugin = () => {
return {
Expand All @@ -30,6 +31,7 @@ const buildInUploaders: IPicGoPlugin = () => {
SMMSUploader(ctx)
imgurUploader(ctx)
awss3Uploader(ctx)
lskyUploader(ctx)
},
}
}
Expand Down
183 changes: 183 additions & 0 deletions libs/Universal-PicGo-Core/src/plugins/uploader/lsky/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
/*
* GNU GENERAL PUBLIC LICENSE
* Version 3, 29 June 2007
*
* Copyright (C) 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 { ILskyConfig, IPicGo, IPluginConfig } from "../../../types"
import { ILocalesKey } from "../../../i18n/zh-CN"
import { base64ToBuffer } from "../../../utils/common"
import { IBuildInEvent } from "../../../utils/enums"
import { AxiosRequestConfig } from "axios"
import { browserPathJoin } from "../../../utils/browserUtils"

const SIYUAN_PICGO_PLUGIN_LSKY_TOKEN_KEY = "siyuan_picgo_plugin_lsky_token"

const getToken = async (ctx: IPicGo, lskyOptions: ILskyConfig): Promise<string> => {
// 先查询配置,存在直接返回
let token = window.localStorage.getItem(SIYUAN_PICGO_PLUGIN_LSKY_TOKEN_KEY) ?? ""
// token 不存在,则调用接口生成 token 并存储
if (token.trim().length == 0) {
const formData = new FormData()
formData.append("email", lskyOptions.email)
formData.append("password", lskyOptions.password)
const res = (await ctx.request({
method: "POST",
url: browserPathJoin(lskyOptions.server, "/api/v1/tokens"),
data: formData,
})) as any

if (!res.status) {
throw new Error("lsky token get error")
}
token = res.data.token
window.localStorage.setItem(SIYUAN_PICGO_PLUGIN_LSKY_TOKEN_KEY, token)
}

return token
}

const postOptions = (lskyOptions: ILskyConfig, fileName: string, token: string, image: Buffer): AxiosRequestConfig => {
const formData = new FormData()
formData.append("file", new Blob([image], { type: "image/png" }), fileName)

// 策略可选
const strategyId = lskyOptions.strategyId ?? ""
if (strategyId.trim().length > 0) {
formData.append("strategy_id", strategyId)
}

return {
method: "POST",
url: browserPathJoin(lskyOptions.server, "/api/v1/upload"),
headers: {
Authorization: `Bearer ${token}`,
Accept: "application/json",
// multipart/form-data 是自动设置的,这里不需要
// "content-type": "multipart/form-data",
},
data: formData,
}
}

const handle = async (ctx: IPicGo): Promise<IPicGo> => {
const lskyOptions = ctx.getConfig<ILskyConfig>("picBed.lsky")
if (!lskyOptions) {
throw new Error("Can't find lsky config")
}

const imgList = ctx.output
for (const img of imgList) {
if (img.fileName) {
let image = img.buffer
if (!image && img.base64Image) {
image = base64ToBuffer(img.base64Image)
}

if (!image) {
ctx.log.error("Can not find image buffer")
throw new Error("Can not find image buffer")
}

try {
const token = await getToken(ctx, lskyOptions)
const options = postOptions(lskyOptions, img.fileName, token, image)
const res: any = await ctx.request(options)

if (res.status) {
delete img.base64Image
delete img.buffer
img.imgUrl = res.data.links.url
} else {
throw new Error("Server error, please try again =>" + res.message)
}
} catch (e: any) {
console.log("lsky error")
console.log(e)

let errMsg: any
if (e?.statusCode) {
errMsg = e.response?.body?.message ?? e.response?.body ?? e.stack ?? "unknown error"
} else {
errMsg = e.toString()
}
ctx.log.error(errMsg)
ctx.emit(IBuildInEvent.NOTIFICATION, {
title: ctx.i18n.translate<ILocalesKey>("UPLOAD_FAILED"),
body: ctx.i18n.translate<ILocalesKey>("CHECK_SETTINGS"),
})
throw errMsg
}
}
}

return ctx
}

const config = (ctx: IPicGo): IPluginConfig[] => {
const userConfig = ctx.getConfig<ILskyConfig>("picBed.lsky") || {}
const config: IPluginConfig[] = [
{
name: "server",
type: "input",
default: userConfig.server || "",
get alias() {
return ctx.i18n.translate<ILocalesKey>("PICBED_ISKY_SERVER")
},
get message() {
return ctx.i18n.translate<ILocalesKey>("PICBED_ISKY_MESSAGE_SERVER")
},
required: true,
},
{
name: "email",
type: "input",
default: userConfig.email || "",
get alias() {
return ctx.i18n.translate<ILocalesKey>("PICBED_ISKY_EMAIL")
},
get message() {
return ctx.i18n.translate<ILocalesKey>("PICBED_ISKY_MESSAGE_EMAIL")
},
required: true,
},
{
name: "password",
type: "password",
default: userConfig.password || "",
get alias() {
return ctx.i18n.translate<ILocalesKey>("PICBED_ISKY_PASSWORD")
},
get message() {
return ctx.i18n.translate<ILocalesKey>("PICBED_ISKY_MESSAGE_PASSWORD")
},
required: true,
},
{
name: "strategyId",
type: "input",
default: userConfig.strategyId || "",
get alias() {
return ctx.i18n.translate<ILocalesKey>("PICBED_ISKY_STRATEGYID")
},
get message() {
return ctx.i18n.translate<ILocalesKey>("PICBED_ISKY_MESSAGE_STRATEGYID")
},
required: false,
},
]
return config
}

export default function register(ctx: IPicGo): void {
ctx.helper.uploader.register("lsky", {
get name() {
return ctx.i18n.translate<ILocalesKey>("PICBED_LSKY")
},
handle,
config,
})
}
8 changes: 8 additions & 0 deletions libs/Universal-PicGo-Core/src/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,14 @@ export interface IAwsS3Config {
corsProxy?: boolean
}

/** 兰空图床配置项 */
export interface ILskyConfig {
server: string
email: string
password: string
strategyId?: string
}

/** PicGo 配置文件类型定义 */
export interface IConfig {
picBed: {
Expand Down

0 comments on commit c26415f

Please sign in to comment.